From 3bff34c3aa7ad412042272ea6a37b7d5b49b8d9b Mon Sep 17 00:00:00 2001
From: zxl <763096477@qq.com>
Date: 星期四, 26 六月 2025 09:09:51 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev
---
pages/tabbar/user/utils/tool.vue | 5
uni_modules/zero-loading/components/zero-loading/static/loading-surround.vue | 91
uni_modules/zero-loading/components/zero-loading/static/loading-sun.vue | 140 +
uni_modules/zero-loading/readme.md | 69
pages/kitchen/KitchenVideo.vue | 2540 +++++++++--------
pages/supplier/suppler-order/suppler-order.vue | 666 ++++
uni_modules/zero-loading/components/zero-loading/static/loading-sword.vue | 81
pages/mine/activity/reportActivity.vue | 25
uni_modules/zero-loading/components/zero-loading/static/loading-radar.vue | 132
uni_modules/zero-loading/components/zero-loading/static/loading-atom.vue | 108
pages/health/healthVideo.vue | 2148 ++++++++-------
pages/tabbar/index/home.vue | 179
uni_modules/zero-loading/components/zero-loading/static/loading-annulus.vue | 45
uni_modules/zero-loading/components/zero-loading/static/loading-bounce.vue | 84
pages/video/video-edit.vue | 22
uni_modules/zero-loading/components/zero-loading/static/loading-pulse.vue | 67
pages/tabbar/cart/cartList.vue | 7
uni_modules/zero-loading/components/zero-loading/static/loading-gear.vue | 118
components/TopBar.vue | 147 +
uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue | 1
components/custom-tabbar.vue | 6
uni_modules/zero-loading/components/zero-loading/static/loading-circle.vue | 96
pages/order/fillorder.vue | 5
uni_modules/zero-loading/changelog.md | 51
api/order.js | 12
pages/product/goods.vue | 20
uni_modules/zero-loading/components/zero-loading/static/loading-locating.vue | 81
pages.json | 26
uni_modules/zero-loading/package.json | 83
pages/video/video-goods-detail.vue | 14
static/mine/order.png | 0
uni_modules/zero-loading/components/zero-loading/static/loading-equal.vue | 81
pages/order/myOrder.vue | 4
uni_modules/zero-loading/components/zero-loading/static/loading-eyes.vue | 78
uni_modules/zero-loading/components/zero-loading/static/loading-photo.vue | 87
pages/tabbar/video/video.vue | 11
components/m-buy/goods.vue | 2
uni_modules/zero-loading/components/zero-loading/static/loading-wobble.vue | 127
uni_modules/zero-loading/components/zero-loading/static/loading-love.vue | 201 +
pages/video/video-play.vue | 199
uni_modules/zero-loading/components/zero-loading/zero-loading.vue | 186 +
pages/commodity-square/commoditySquare.vue | 106
pages/video/home-page.vue | 52
43 files changed, 5,683 insertions(+), 2,520 deletions(-)
diff --git a/api/order.js b/api/order.js
index a718297..d1cc985 100644
--- a/api/order.js
+++ b/api/order.js
@@ -57,6 +57,18 @@
params,
});
}
+/**
+ * 鑾峰彇璁㈠崟鍒楄〃
+ * @param params
+ */
+export function getOrderXcxList(params) {
+ return http.request({
+ url: "/order/order/xcx",
+ method: Method.GET,
+ needToken: true,
+ params,
+ });
+}
/**
* 鑾峰彇璁㈠崟璇︽儏
diff --git a/components/TopBar.vue b/components/TopBar.vue
new file mode 100644
index 0000000..b1d6ffe
--- /dev/null
+++ b/components/TopBar.vue
@@ -0,0 +1,147 @@
+<template>
+ <view class="top-bar" :style="{paddingTop: statusBarHeight + 'px'}">
+ <view class="top-bar-content">
+ <!-- 鏍囬鍒楄〃 -->
+ <scroll-view class="title-scroll" scroll-x="true" scroll-with-animation :scroll-left="scrollLeft">
+ <view class="title-container">
+ <view
+ v-for="(item, index) in titleList"
+ :key="index"
+ :class="{active: selectedTitleIndex === item.index, 'title-item': true}"
+ :style="{color: textColor}"
+ @click="changeTab(item)"
+ >
+ <text>{{item.title}}</text>
+ <view class="underline" :style="{backgroundColor: textColor}" v-if="selectedTitleIndex === item.index"></view>
+ </view>
+ </view>
+ </scroll-view>
+ </view>
+ </view>
+</template>
+
+<script>
+ export default {
+ name:"TopBar",
+ props: {
+ selectedTitleIndex: {
+ type: String,
+ default: 'home'
+ },
+ textColor: {
+ type: String,
+ default: 'white'
+ }
+ },
+ data() {
+ return {
+ statusBarHeight: 0,
+ scrollLeft: 0,
+ titleList: [
+ {
+ index: 'home',
+ pagePath: '/pages/tabbar/index/home',
+ title: '鎺ㄨ崘'
+ },
+ {
+ index: 'shop',
+ pagePath: '/pages/commodity-square/commoditySquare',
+ title: '鍟嗗搧骞垮満'
+ },
+ {
+ index: 'activity',
+ pagePath: '/pages/mine/activity/reportActivity',
+ title: '娲诲姩'
+ },
+ {
+ index: 'health',
+ pagePath: '/pages/health/healthVideo',
+ title: '澶у仴搴�'
+ }
+ ]
+ };
+ },
+ created() {
+ // 鑾峰彇鐘舵�佹爮楂樺害
+ const systemInfo = uni.getSystemInfoSync();
+ this.statusBarHeight = systemInfo.statusBarHeight;
+ },
+ methods: {
+ changeTab(titleObj) {
+ console.log("鐐瑰嚮椤堕儴瀵艰埅", titleObj);
+ if (titleObj.index !== this.selectedTitleIndex) {
+ this.$emit("changeTab", titleObj);
+ // 璁$畻婊氬姩浣嶇疆浣垮綋鍓嶉�変腑椤瑰眳涓�
+ this.$nextTick(() => {
+ const query = uni.createSelectorQuery().in(this);
+ query.select(`.title-item[data-index="${titleObj.index}"]`).boundingClientRect();
+ query.select('.title-scroll').boundingClientRect();
+ query.exec(res => {
+ if (res[0] && res[1]) {
+ const itemLeft = res[0].left;
+ const scrollWidth = res[1].width;
+ const itemWidth = res[0].width;
+ this.scrollLeft = itemLeft - (scrollWidth - itemWidth) / 2;
+ }
+ });
+ });
+ }
+ }
+ }
+ }
+</script>
+
+<style>
+ .top-bar {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: 999;
+ }
+
+ .top-bar .top-bar-content {
+ box-sizing: border-box;
+ display: flex;
+ align-items: center;
+ }
+
+ .top-bar .title-scroll {
+ width: 100%;
+ height: 80rpx;
+ white-space: nowrap;
+ }
+
+ .top-bar .title-scroll .title-container {
+ display: inline-flex;
+ height: 100%;
+ align-items: center;
+ }
+
+ .top-bar .title-scroll .title-container .title-item {
+ position: relative;
+ padding: 0 24rpx;
+ font-size: 32rpx;
+ /* color: white; */
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-direction: column;
+ }
+
+ .top-bar .title-scroll .title-container .title-item.active {
+ font-weight: 500;
+ }
+
+ .top-bar .title-scroll .title-container .title-item.active .underline {
+ position: absolute;
+ bottom: 4rpx;
+ left: 50%;
+ transform: translateX(-50%);
+ width: calc(100% - 76rpx);
+ height: 4rpx;
+ /* background-color: white; */
+ border-radius: 4rpx;
+ }
+</style>
\ No newline at end of file
diff --git a/components/custom-tabbar.vue b/components/custom-tabbar.vue
index 75aec2e..7d29bed 100644
--- a/components/custom-tabbar.vue
+++ b/components/custom-tabbar.vue
@@ -48,12 +48,12 @@
},
{
// "pagePath": "/pages/tabbar/category/category",
- "pagePath": "/pages/commodity-square/commoditySquare",
+ "pagePath": "/pages/kitchen/KitchenVideo",
"iconPath": "/static/tabbar/category.png",
"selectedIconPath": "/static/tabbar/category-s.png",
- "text": "鍟嗗煄",
- "key": 'shop'
+ "text": "绁炲帹",
+ "key": 'kitchen'
},
{
"pagePath": "/pages/tabbar/video/video",
diff --git a/components/m-buy/goods.vue b/components/m-buy/goods.vue
index 7217bbb..e3d7c8d 100644
--- a/components/m-buy/goods.vue
+++ b/components/m-buy/goods.vue
@@ -5,7 +5,7 @@
<view class="goods-box bottom">
<view class="goods-header">
<view class="goods-img">
- <u-image width="200rpx" border-radius="20" class="uimage" height="200rpx" :src="selectedSpecImg ? selectedSpecImg : goodsDetail.thumbnail"></u-image>
+ <!-- <u-image width="200rpx" border-radius="20" class="uimage" height="200rpx" :src="selectedSpecImg ? selectedSpecImg : goodsDetail.thumbnail"></u-image> -->
</view>
<view class="goods-skus">
<!-- 鏈夋椿鍔ㄥ晢鍝佷环鏍� -->
diff --git a/pages.json b/pages.json
index 68e223e..48cdf4f 100644
--- a/pages.json
+++ b/pages.json
@@ -36,6 +36,13 @@
}
},
{
+ "path": "pages/kitchen/KitchenVideo",
+ "style": {
+ "navigationBarTitleText": "绁炲帹",
+ "navigationStyle": "custom" // 闅愯棌绯荤粺瀵艰埅鏍�
+ }
+ },
+ {
"path": "pages/tabbar/home/title",
"style": {
"navigationBarTitleText": "娑堟伅"
@@ -68,7 +75,7 @@
"style": {
"navigationBarTitleText": "鍟嗗搧骞垮満",
- // "navigationStyle": "custom", // 闅愯棌绯荤粺瀵艰埅鏍�
+ "navigationStyle": "custom", // 闅愯棌绯荤粺瀵艰埅鏍�
"navigationBarTextStyle": "black",
// "disableScroll": true,
"bounce": "none",
@@ -785,6 +792,7 @@
"style": {
"navigationBarTitleText": "娲诲姩",
"enablePullDownRefresh": true, //涓嬫媺鍒锋柊
+ "navigationStyle": "custom", // 闅愯棌椤堕儴瀵艰埅鏍�
"componentPlaceholder": {
"u-form": "view",
"u-form-item": "view",
@@ -1471,16 +1479,8 @@
"pages": [{
"path": "healthVideo",
"style": {
- "navigationBarTitleText": "澶у仴搴�"
- }
- }]
- },
- {
- "root": "pages/kitchen",
- "pages": [{
- "path": "KitchenVideo",
- "style": {
- "navigationBarTitleText": "鍘ㄧ"
+ "navigationBarTitleText": "澶у仴搴�",
+ "navigationStyle": "custom"
}
}]
}
@@ -1523,10 +1523,10 @@
},
{
// "pagePath": "pages/tabbar/category/category",
- "pagePath": "pages/commodity-square/commoditySquare",
+ "pagePath": "pages/kitchen/KitchenVideo",
"iconPath": "static/tabbar/category.png",
"selectedIconPath": "static/tabbar/category-s.png",
- "text": "鍟嗗煄"
+ "text": "绁炲帹"
},
{
"pagePath": "pages/tabbar/video/video",
diff --git a/pages/commodity-square/commoditySquare.vue b/pages/commodity-square/commoditySquare.vue
index 6226f83..8a0e232 100644
--- a/pages/commodity-square/commoditySquare.vue
+++ b/pages/commodity-square/commoditySquare.vue
@@ -1,5 +1,6 @@
<template>
<view class="container">
+ <top-bar selectedTitleIndex="shop" textColor="black" @changeTab="topBarChange" class="topBar"></top-bar>
<input type="text" v-show="false" v-model="flushDom" />
<view class="search">
<u-search class="nav-search" @blur='searchGoods' placeholder="鎼滅储鍟嗗搧" :show-action="false"></u-search>
@@ -8,17 +9,17 @@
<view class="left" style="width: 310rpx;">
<view class="commoditySquareItem" v-for="(item,index) in goodsList1"
@click="goToGoodsInfo('goodsList1',item.id)">
- <video :src="item.goodsVideo" v-if="item.goodsVideo " v-show="item.show" :initial-time="0"
+ <!-- <video :src="item.goodsVideo" v-if="item.goodsVideo " v-show="item.show" :initial-time="0"
:controls="false" object-fit="contain" :show-play-btn="false" :show-center-play-btn="false"
@loadedmetadata="getvideoInfo($event,'goodsList1',index)" :ref="'video'+item.id"
- :style="{width:item.width,height:item.height}"></video>
- <image :src="item.thumbnail" v-if="item.goodsVideo ==null || item.goodsVideo == ''"
+ :style="{width:item.width,height:item.height}"></video> -->
+ <image :src="item.thumbnail"
mode="aspectFill" class="goodsImg">
</image>
<view class="goodsInfo">
- <view class="">{{item.goodsName}}</view>
+ <view class="goodsName">{{item.goodsName}}</view>
<view class="priceInfo">
- <view class="">锟{item.price}}</view>
+ <view class="goodsPrice">锟{item.price}}</view>
<view class="">宸插敭: {{item.buyCount}}</view>
</view>
</view>
@@ -27,17 +28,17 @@
<view class="right" style="width: 310rpx;">
<view class="commoditySquareItem" v-for="(item,index) in goodsList2"
@click="goToGoodsInfo('goodsList2',item.id)">
- <video :src="item.goodsVideo" v-if="item.goodsVideo " v-show="item.show" :initial-time="0"
+<!-- <video :src="item.goodsVideo" v-if="item.goodsVideo " v-show="item.show" :initial-time="0"
:controls="false" object-fit="contain" :show-play-btn="false" :show-center-play-btn="false"
@loadedmetadata="getvideoInfo($event,'goodsList2',index)" :ref="'video'+item.id"
- :style="{width:item.width,height:item.height}"></video>
- <image :src="item.thumbnail" v-if="item.goodsVideo ==null || item.goodsVideo == ''"
+ :style="{width:item.width,height:item.height}"></video> -->
+ <image :src="item.thumbnail"
mode="aspectFill" class="goodsImg">
</image>
<view class="goodsInfo">
- <view class="">{{item.goodsName}}</view>
+ <view class="goodsName">{{item.goodsName}}</view>
<view class="priceInfo">
- <view class="">锟{item.price}}</view>
+ <view class="goodsPrice">锟{item.price}}</view>
<view class="">宸插敭: {{item.buyCount}}</view>
</view>
</view>
@@ -48,7 +49,7 @@
<view class="openShowLeft" @click="showDrawer('showLeft')" v-if="!showLeft">
<uni-icons type="right" size="30"></uni-icons>
</view>
- <uni-drawer ref="showLeft" mode="left" width="120" height="94vh" @change="change($event,'showLeft')"
+ <uni-drawer ref="showLeft" mode="left" width="120" height="80vh" @change="change($event,'showLeft')"
:cus-style="true" class="navigationLeft">
<scroll-view class="typeNavigation" :scroll-y="true" show-scrollbar="false">
<view class="typeNavigationItem" :class="{typeNavigationItemCheck:currentCategort ==item.id}"
@@ -60,11 +61,11 @@
</view>
<view style="display: flex;align-items: center;justify-content: center;margin-top: 20rpx;" v-if="canLoadMore">
娌℃湁鏇村鏁版嵁浜�.................</view>
- <custom-tabbar bgColor="#ffffff" selected="shop"></custom-tabbar>
</view>
</template>
<script>
+ import TopBar from "@/components/TopBar.vue";
import {
getCategoryList,
getGoodsList
@@ -73,6 +74,7 @@
getSTSToken
} from '@/api/common.js'
export default {
+ components: {TopBar},
data() {
return {
//璁板綍涓ゅ垪楂樺害
@@ -96,6 +98,7 @@
pageSize: 12,
pageNumber: 1,
categoryId: null,
+ canFilter:true
},
//鍟嗗搧鍙屽垪鏄剧ず
goodsList1: [],
@@ -103,6 +106,17 @@
}
},
methods: {
+ topBarChange(titleObj) {
+ if (titleObj.index === 'home') {
+ uni.switchTab({
+ url: titleObj.pagePath
+ });
+ } else {
+ uni.redirectTo({
+ url: titleObj.pagePath
+ });
+ }
+ },
async searchGoods(keyWard) {
this.getGoodsParam.keyword = keyWard
this.getGoodsParam.pageNumber = 1
@@ -165,19 +179,19 @@
},
async getgoodsData() {
const goodsList = await getGoodsList(this.getGoodsParam);
- const sts = await getSTSToken();
- const stsUrl = sts.data.data.endpoint
- // 澶勭悊鏁版嵁
- goodsList.data.result.records.forEach(item => {
- if (item.thumbnail !== '' && item.thumbnail !== null && item.thumbnail.indexOf('http') ===
- -1) {
- item.thumbnail = stsUrl + '/' + item.thumbnail
- }
- if (item.goodsVideo !== '' && item.goodsVideo !== null && item.goodsVideo.indexOf(
- 'http') === -1) {
- item.goodsVideo = stsUrl + '/' + item.goodsVideo
- }
- })
+ // const sts = await getSTSToken();
+ // const stsUrl = sts.data.data.endpoint
+ // // 澶勭悊鏁版嵁
+ // goodsList.data.result.records.forEach(item => {
+ // if (item.thumbnail !== '' && item.thumbnail !== null && item.thumbnail.indexOf('http') ===
+ // -1) {
+ // item.thumbnail = stsUrl + '/' + item.thumbnail
+ // }
+ // if (item.goodsVideo !== '' && item.goodsVideo !== null && item.goodsVideo.indexOf(
+ // 'http') === -1) {
+ // item.goodsVideo = stsUrl + '/' + item.goodsVideo
+ // }
+ // })
//璁$畻涓や釜鏁扮粍鐨勯暱搴� 鐢ㄤ簬瑙e喅鐎戝竷娴佷袱杈归珮搴︿笉涓�鑷撮棶棰�
//骞冲垎缁欎袱涓暟缁�
const goodsSize = goodsList.data.result.records.length;
@@ -289,7 +303,7 @@
.openShowLeft {
position: fixed;
- top: 120rpx;
+ top: 200rpx;
left: 0;
align-items: center;
justify-content: flex-start;
@@ -317,11 +331,11 @@
flex: 1
}
- .priceInfo {
- margin-top: 10rpx;
- display: flex;
- justify-content: space-around;
- }
+ // .priceInfo {
+ // margin-top: 10rpx;
+ // display: flex;
+ // justify-content: space-around;
+ // }
// 澶勭悊鎶藉眽鍐呭婊氬姩
.scroll-view-box {
@@ -370,4 +384,32 @@
// width: 500rpx;
// z-index: 9999;
}
-</style>
\ No newline at end of file
+ .goodsInfo{
+ margin-top: 10rpx;
+ box-sizing: border-box;
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ }
+ .goodsName{
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+ .priceInfo{
+ margin-top: 10rpx;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+ .goodsPrice{
+ color: red;
+ font-weight: bold;
+ }
+ .topBar {
+ position: fixed;
+ top: 20rpx;
+ left: 20rpx;
+ z-index: 1000
+ }
+</style>
diff --git a/pages/health/healthVideo.vue b/pages/health/healthVideo.vue
index 60167e1..8fef229 100644
--- a/pages/health/healthVideo.vue
+++ b/pages/health/healthVideo.vue
@@ -1,910 +1,1048 @@
<template>
- <view class="video-container">
- <!-- 瑙嗛鍒楄〃 -->
- <swiper class="video-swiper" vertical circular :current="currentIndex" @change="onSwiperChange">
- <swiper-item v-for="(item, index) in videoList" :key="item.id">
- <view style="width: 100%;height: 100%;" v-if="item.videoContentType === 'video'">
- <!-- 鎾斁鎸夐挳锛堜粎褰撹棰戞殏鍋滄椂鏄剧ず锛� -->
- <view class="play-icon" @click="togglePlay(index)" v-if="!currentVideoIsPlaying">
- <image src="/static/video/play.png" style="width: 45px;height: 45px" mode="aspectFit"></image>
- </view>
- <video :id="'video'+index" :ref="'video'+index" :src="item.videoUrl"
- :autoplay="currentIndex === index" :controls="false" :loop="true" :object-fit="item.objectFit"
- :enable-progress-gesture="false" class="video-item" @play="onPlay(item.id, index)"
- @pause="onPause(index)" @ended="onEnded(index)" @click="togglePlay(index)"
- @timeupdate="onTimeUpdate($event)" @loadedmetadata="onLoadedMetadata($event)"></video>
- <!-- 鑷畾涔夋帶鍒舵潯 -->
- <view @touchstart="handleTouchStart" @touchmove="handleTouchMove" @touchend="handleTouchEnd"
- class="container">
- <!-- 杩涘害鏉� - 鏁翠釜鍖哄煙鍙嫋鍔� -->
- <view class="process-warp" :style="{ opacity: showProcess ? 1 : 0 }">
- <!-- 鏄剧ず褰撳墠杩涘害 -->
- <view class="progress-text">{{ hasPlayTime }}/{{formartDuration[index]}}</view>
- <view class="progress-bar" id="progressBar">
+ <view class="video-container">
+ <top-bar selectedTitleIndex="health" textColor="black" @changeTab="topBarChange" class="topBar"></top-bar>
+ <!-- 瑙嗛鍔犺浇 -->
+ <zero-loading v-show="videoLoading" type="circle" color="#0ebd57" text=""></zero-loading>
+ <!-- 瑙嗛鍒楄〃 -->
+ <swiper
+ class="video-swiper"
+ vertical
+ :current="currentIndex"
+ @change="onSwiperChange"
+ :duration="250"
+ easing-function="linear"
+ >
+ <swiper-item
+ v-for="(item, index) in videoList"
+ :key="item.id"
+ @touchstart="handleSwiperStart"
+ @touchmove="handleSwiperMove"
+ @touchend="handleSwiperEnd(item)"
+ >
+ <view style="width: 100%;height: 100%;" v-if="item.videoContentType === 'video'">
+ <!-- 鎾斁鎸夐挳锛堜粎褰撹棰戞殏鍋滄椂鏄剧ず锛� -->
+ <view
+ class="play-icon"
+ @click="togglePlay(index)"
+ v-show="!currentVideoIsPlaying"
+ >
+ <image src="/static/video/play.png" style="width: 45px;height: 45px" mode="aspectFit"></image>
+ </view>
+ <video
+ v-if="index >= currentIndex - videoLiveOffset && index <= currentIndex + videoLiveOffset"
+ :id="'video'+index"
+ :ref="'video'+index"
+ :src="item.videoUrl"
+ :autoplay="index === currentIndex"
+ :controls="false"
+ :loop="true"
+ :object-fit="item.objectFit"
+ :enable-progress-gesture="false"
+ :show-center-play-btn="false"
+ class="video-item"
+ @play="onPlay(item.id, index)"
+ @pause="onPause(index)"
+ @ended="onEnded(index)"
+ @click="togglePlay(index)"
+ @timeupdate="onTimeUpdate($event)"
+ @loadedmetadata="onLoadedMetadata($event)"
+ @waiting="videoWaiting(index)"
+ ></video>
+ <!-- 鑷畾涔夋帶鍒舵潯 -->
+ <view
+ @touchstart.stop="handleTouchStart"
+ @touchmove.stop="handleTouchMove"
+ @touchend.stop="handleTouchEnd"
+ class="container">
+ <!-- 杩涘害鏉� - 鏁翠釜鍖哄煙鍙嫋鍔� -->
+ <view class="process-warp" :style="{ opacity: showProcess ? 1 : 0 }">
+ <!-- 鏄剧ず褰撳墠杩涘害 -->
+ <view class="progress-text">{{ hasPlayTime }}/{{formartDuration}}</view>
+ <view
+ class="progress-bar"
+ id="progressBar"
+ >
- <!-- 宸插~鍏呴儴鍒� -->
- <view class="progress-fill" :style="{ width: progress + '%' }"></view>
- </view>
- </view>
- </view>
+ <!-- 宸插~鍏呴儴鍒� -->
+ <view class="progress-fill" :style="{ width: progress + '%' }"></view>
+ </view>
</view>
- <view style="width: 100%; height: 100%;" v-else-if="item.videoContentType === 'img'">
- <uni-swiper-dot :info="item.imgs" :current="currentImgIndex" mode="round"
- style="width: 100%;height: 100%;display: flex;justify-content: center;align-items: center;"
- :dots-styles="{width: 24, bottom: 24,selectedBackgroundColor: 'green', backgroundColor: 'gray'}">
- <swiper class="swiper-box" @change="imgChange" :autoplay="true" :interval="3000">
- <swiper-item v-for="img in item.imgs" :key="img">
- <view class="swiper-item">
- <!-- 璋冩暣 image 鏍峰紡锛屼娇鍏跺眳涓笖鎸夋瘮渚嬬缉鏀� -->
- <image :src="img" mode="aspectFit"
- style="width: 100%; height: 100%; display: block; margin: 0 auto;"></image>
- </view>
- </swiper-item>
- </swiper>
- </uni-swiper-dot>
- </view>
+ </view>
+ </view>
+ <view style="width: 100%; height: 100%;" v-else-if="item.videoContentType === 'img'">
+ <uni-swiper-dot
+ :info="item.imgs"
+ :current="currentImgIndex"
+ mode="round"
+ style="width: 100%;height: 100%;display: flex;justify-content: center;align-items: center;"
+ :dots-styles="{width: 24, bottom: 24,selectedBackgroundColor: 'green', backgroundColor: 'gray'}"
+ >
+ <swiper class="swiper-box" @change="imgChange" :autoplay="true" :interval="3000">
+ <swiper-item v-for="img in item.imgs" :key="img">
+ <view class="swiper-item">
+ <!-- 璋冩暣 image 鏍峰紡锛屼娇鍏跺眳涓笖鎸夋瘮渚嬬缉鏀� -->
+ <image
+ :src="img"
+ mode="aspectFit"
+ style="width: 100%; height: 100%; display: block; margin: 0 auto;"
+ ></image>
+ </view>
+ </swiper-item>
+ </swiper>
+ </uni-swiper-dot>
+ </view>
- <!-- 鎮寕鍟嗗搧閾炬帴灞� -->
- <view class="goods-link-warp" v-if="false">
- <view class="goods-link">
- <view class="goods-container">
- <!-- 鍟嗗搧鍥剧墖 -->
- <image class="goods-image" :src="item.goods.imageUrl" mode="aspectFill"></image>
+ <!-- 鎮寕鍟嗗搧閾炬帴灞� -->
+ <view class="goods-link-warp" v-if="item.goodsList.length > 0">
+ <view class="goods-link">
+ <swiper @change="goodsChange" :autoplay="true" :interval="4000" style="height: 120rpx;">
+ <swiper-item v-for="goods in item.goodsList" :key="goods.goodsId">
+ <view class="goods-container" @click="jumpToPay(item.id)">
+ <!-- 鍟嗗搧鍥剧墖 -->
+ <image class="goods-image" :src="goods.thumbnail" mode="aspectFill"></image>
- <!-- 鍟嗗搧淇℃伅 -->
- <view class="goods-info">
- <text class="goods-name">{{item.goods.name}}</text>
- <view class="price-section">
- <text class="current-price">楼{{item.goods.price}}</text>
- <text class="original-price"
- v-if="item.goods.originalPrice">楼{{item.goods.originalPrice}}</text>
- </view>
- <text class="sales-count">{{item.goods.saleNum}}浜哄凡璐�</text>
- </view>
-
- <!-- 璐拱鎸夐挳 -->
- <view class="buy-button">
- <text>璐拱</text>
- </view>
- </view>
+ <!-- 鍟嗗搧淇℃伅 -->
+ <view class="goods-info">
+ <text class="goods-name">{{goods.goodsName}}</text>
+ <view class="price-section">
+ <text class="current-price">楼{{goods.price}}</text>
+ <text class="original-price" v-if="goods.originalPrice">楼{{goods.originalPrice}}</text>
+ </view>
</view>
- </view>
+ </view>
+ </swiper-item>
+ </swiper>
+ </view>
+ </view>
- <!-- 瑙嗛淇℃伅灞� -->
- <view class="video-info">
- <view>
- <text class="video-author">@{{item.authorName}}</text>
- </view>
- <view style="width: 100%;word-wrap: break-word;white-space: normal;overflow-wrap: break-word;">
- <text class="video-title">{{item.title}}</text>
- <text class="video-tag" v-for="(tag, index) in item.tagList"
- :key="tag.id">#{{tag.tagName}}</text>
- </view>
- </view>
+ <!-- 瑙嗛淇℃伅灞� -->
+ <view class="video-info">
+ <view>
+ <text class="video-author">@{{item.authorName}}</text>
+ </view>
+ <view style="width: 100%;word-wrap: break-word;white-space: normal;overflow-wrap: break-word;">
+ <text class="video-title">{{item.title}}</text>
+ <text class="video-tag" v-for="(tag, index) in item.tagList" :key="tag.id">#{{tag.tagName}}</text>
+ </view>
+ </view>
- <!-- 鍙充晶浜掑姩鎸夐挳 -->
- <view class="action-buttons" v-if="false">
- <view class="avatar-container">
- <image class="avatar" @click="jumpToHomePage(item.authorId)" :src="item.authorAvatar"
- mode="aspectFill"></image>
- <!-- 鍏虫敞鍥炬爣 - 浣跨敤缁濆瀹氫綅 -->
- <view v-if="!item.subscribeThisAuthor" class="follow-icon"
- @click="subscribeAuth(index, item.authorId)">
- <text class="iconfont"></text>
- </view>
- </view>
- <view class="action-item" @click="toggleCollect(item, index)">
- <text class="iconfont" v-if="item.collected"></text>
- <text class="iconfont" v-else></text>
- <text style="font-size: 10px;font-weight: lighter;">{{item.collectNum}}</text>
- </view>
- <view class="action-item" @click="showComments(item)">
- <text class="iconfont"></text>
- <text style="font-size: 10px;font-weight: lighter;">{{item.commentNum}}</text>
- </view>
- </view>
+ <!-- 鍙充晶浜掑姩鎸夐挳 -->
+ <view class="action-buttons" v-if="false">
+ <view class="avatar-container">
+ <image class="avatar" @click="jumpToHomePage(item.authorId)" :src="item.authorAvatar" mode="aspectFill"></image>
+ <!-- 鍏虫敞鍥炬爣 - 浣跨敤缁濆瀹氫綅 -->
+ <view v-if="!item.subscribeThisAuthor" class="follow-icon" @click="subscribeAuth(index, item.authorId)">
+ <text class="iconfont"></text>
+ </view>
+ </view>
+ <view class="action-item" @click="toggleCollect(item, index)">
+ <text class="iconfont" v-if="item.collected"></text>
+ <text class="iconfont" v-else></text>
+ <text style="font-size: 10px;font-weight: lighter;">{{item.collectNum}}</text>
+ </view>
+ <view class="action-item" @click="showComments(item)">
+ <text class="iconfont"></text>
+ <text style="font-size: 10px;font-weight: lighter;">{{item.commentNum}}</text>
+ </view>
+ <view class="action-item">
+ <button open-type="share" class="custom-share-btn" :data-obj="item">
+ <text class="iconfont"></text>
+ </button>
- </swiper-item>
- </swiper>
+ </view>
+ </view>
- <!-- 璇勮寮圭獥 -->
- <uni-popup ref="commentPopup" type="bottom" :is-mask-click="true" @maskClick="closeCommentPopup">
- <view class="comment-popup">
- <view class="popup-header">
- <text class="popup-title" v-if="!commentForm.replyId">璇勮({{commentsTotal}})</text>
- <view class="reply-title" v-else>
- <text>鍥炲 @{{commentForm.replyUserNickname}}</text>
- <text class="cancel-reply" @click="cancelReply">鍙栨秷</text>
- </view>
- <text class="iconfont close-icon" @click="closeCommentPopup"></text>
- </view>
+ </swiper-item>
+ </swiper>
- <scroll-view class="comment-list" scroll-y :show-scrollbar="false" @scrolltolower="getCommentPage">
- <view v-if="commentLoading" class="loading">
- <uni-load-more status="loading"></uni-load-more>
- </view>
+ <!-- 璇勮寮圭獥 -->
+ <uni-popup ref="commentPopup" type="bottom" :is-mask-click="true" @maskClick="closeCommentPopup">
+ <view class="comment-popup">
+ <view class="popup-header">
+ <text class="popup-title" v-if="!commentForm.replyId">璇勮({{commentsTotal}})</text>
+ <view class="reply-title" v-else>
+ <text>鍥炲 @{{commentForm.replyUserNickname}}</text>
+ <text class="cancel-reply" @click="cancelReply">鍙栨秷</text>
+ </view>
+ <text class="iconfont close-icon" @click="closeCommentPopup"></text>
+ </view>
- <view v-else-if="comments.length === 0" class="empty">
- 鏆傛棤璇勮锛屽揩鏉ュ彂琛ㄧ涓�鏉¤瘎璁哄惂~
- </view>
+ <scroll-view class="comment-list" scroll-y :show-scrollbar="false" @scrolltolower="getCommentPage">
+ <view v-if="commentLoading" class="loading">
+ <uni-load-more status="loading"></uni-load-more>
+ </view>
- <view v-else class="comment-item" v-for="(comment, index) in comments" :key="comment.id">
- <view style="display: flex;">
- <image class="comment-avatar" :src="comment.userAvatar || '/static/default-avatar.png'">
- </image>
- <view class="comment-content">
- <text class="nickname">{{comment.userNickname}}</text>
- <text class="content">{{comment.commentContent}}</text>
- <view style="position: relative;">
- <text class="time">{{formatTime(comment.createTime)}}</text>
- <text @click="openReply(comment)" class="reply-btu time">鍥炲</text>
- <text v-if="!comment.hasThumbsUp" class="thumbs-up time iconfont"
- @click="thubmsUp(comment.id, index, null)"><text
- v-show="comment.thumbsUpNum > 0"
- class="thumbs-num">{{comment.thumbsUpNum}}</text></text>
- <text v-else class="thumbs-up time iconfont"
- @click="cancelThumbsUp(comment.id, index, null)"><text
- v-show="comment.thumbsUpNum > 0"
- class="thumbs-num">{{comment.thumbsUpNum}}</text></text>
- </view>
- </view>
- </view>
- <!-- 鍥炲鍒楄〃 -->
- <view class="reply-list" v-if="comment.replies && comment.replies.length > 0">
- <view class="reply-item" v-for="(reply, replyIndex) in comment.replies" :key="reply.id">
- <view class="reply-content">
- <view style="display: flex;">
- <image class="comment-reply-avatar"
- :src="reply.replyUserAvatar || '/static/default-avatar.png'"></image>
- <text class="nickname">{{reply.userNickname}}</text>
- <text v-if="reply.replyUserId && reply.masterCommentId !== reply.replyId"
- class="reply-to"><text style="margin-right: 10rpx;font-size: 28rpx;"
- class="iconfont"></text>{{reply.replyUserNickname}}</text>
- </view>
- <text class="content">{{reply.commentContent}}</text>
- <view class="reply-footer">
- <text class="time">{{formatTime(reply.createTime)}}</text>
- <text @click="openReply(comment, reply)" class="reply-btu time">鍥炲</text>
- <text v-if="!reply.hasThumbsUp" class="thumbs-up time iconfont"
- @click="thubmsUp(reply.id, index, replyIndex)"><text
- v-show="reply.thumbsUpNum > 0"
- class="thumbs-num">{{reply.thumbsUpNum}}</text></text>
- <text v-else class="thumbs-up time iconfont"
- @click="cancelThumbsUp(reply.id, index, replyIndex)"><text
- v-show="reply.thumbsUpNum > 0"
- class="thumbs-num">{{reply.thumbsUpNum}}</text></text>
- </view>
- </view>
- </view>
- </view>
- <view class="view-more-replies" v-if="comment.replyTotalCount > 0 && !comment.expandReply"
- @click="loadRepliesPage(comment, index)">
- <text class="line">鈥斺��</text>灞曞紑{{comment.replyTotalCount}}鏉″洖澶� 鈫�
- </view>
- <view class="reply-op"
- v-if="comment.replyTotalCount > replyCommentQuery.pageNumber * replyCommentQuery.pageSize && comment.expandReply">
- <view @click="loadNextPageReply(index)" class="reply-op-item"><text
- class="line">鈥斺��</text>灞曞紑鏇村<text class="iconfont textSideIcon"></text></view>
- <view @click="retractReplyComment(index)" class="reply-op-item" style="margin-left: 50rpx;">
- 鏀惰捣<text class="iconfont textSideIcon"></text></view>
- </view>
- <view class="reply-op"
- v-else-if="comment.replyTotalCount <= replyCommentQuery.pageNumber * replyCommentQuery.pageSize && comment.expandReply">
- <view @click="retractReplyComment(index)" class="reply-op-item"><text
- class="line">鈥斺��</text>鏀惰捣<text class="iconfont textSideIcon"></text></view>
- </view>
- </view>
- </scroll-view>
- <view class="comment-input-area">
- <input ref="commentInput" class="comment-input" v-model="commentForm.commentContent"
- :placeholder="commentForm.replyId ? `鍥炲 @${commentForm.replyUserNickname}` : '鍐欎笅浣犵殑璇勮...'"
- placeholder-class="placeholder" />
- <button class="submit-btn" @click="submitComment"
- :disabled="!commentForm.commentContent.trim()">鍙戦��</button>
+ <view v-else-if="comments.length === 0" class="empty">
+ 鏆傛棤璇勮锛屽揩鏉ュ彂琛ㄧ涓�鏉¤瘎璁哄惂~
+ </view>
+
+ <view v-else class="comment-item" v-for="(comment, index) in comments" :key="comment.id">
+ <view style="display: flex;">
+ <image class="comment-avatar" :src="comment.userAvatar || '/static/default-avatar.png'"></image>
+ <view class="comment-content">
+ <text class="nickname">{{comment.userNickname}}</text>
+ <text class="content">{{comment.commentContent}}</text>
+ <view style="position: relative;">
+ <text class="time">{{formatTime(comment.createTime)}}</text>
+ <text @click="openReply(comment)" class="reply-btu time">鍥炲</text>
+ <text v-if="!comment.hasThumbsUp" class="thumbs-up time iconfont" @click="thubmsUp(comment.id, index, null)"><text v-show="comment.thumbsUpNum > 0" class="thumbs-num">{{comment.thumbsUpNum}}</text></text>
+ <text v-else class="thumbs-up time iconfont" @click="cancelThumbsUp(comment.id, index, null)"><text v-show="comment.thumbsUpNum > 0" class="thumbs-num">{{comment.thumbsUpNum}}</text></text>
+ </view>
</view>
</view>
- </uni-popup>
+ <!-- 鍥炲鍒楄〃 -->
+ <view class="reply-list" v-if="comment.replies && comment.replies.length > 0">
+ <view class="reply-item" v-for="(reply, replyIndex) in comment.replies" :key="reply.id">
+ <view class="reply-content">
+ <view style="display: flex;">
+ <image class="comment-reply-avatar" :src="reply.replyUserAvatar || '/static/default-avatar.png'"></image>
+ <text class="nickname">{{reply.userNickname}}</text>
+ <text v-if="reply.replyUserId && reply.masterCommentId !== reply.replyId" class="reply-to"><text style="margin-right: 10rpx;font-size: 28rpx;" class="iconfont"></text>{{reply.replyUserNickname}}</text>
+ </view>
+ <text class="content">{{reply.commentContent}}</text>
+ <view class="reply-footer">
+ <text class="time">{{formatTime(reply.createTime)}}</text>
+ <text @click="openReply(comment, reply)" class="reply-btu time">鍥炲</text>
+ <text v-if="!reply.hasThumbsUp" class="thumbs-up time iconfont" @click="thubmsUp(reply.id, index, replyIndex)"><text v-show="reply.thumbsUpNum > 0" class="thumbs-num">{{reply.thumbsUpNum}}</text></text>
+ <text v-else class="thumbs-up time iconfont" @click="cancelThumbsUp(reply.id, index, replyIndex)"><text v-show="reply.thumbsUpNum > 0" class="thumbs-num">{{reply.thumbsUpNum}}</text></text>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view class="view-more-replies" v-if="comment.replyTotalCount > 0 && !comment.expandReply" @click="loadRepliesPage(comment, index)">
+ <text class="line">鈥斺��</text>灞曞紑{{comment.replyTotalCount}}鏉″洖澶� 鈫�
+ </view>
+ <view class="reply-op" v-if="comment.replyTotalCount > replyCommentQuery.pageNumber * replyCommentQuery.pageSize && comment.expandReply">
+ <view @click="loadNextPageReply(index)" class="reply-op-item"><text class="line">鈥斺��</text>灞曞紑鏇村<text class="iconfont textSideIcon"></text></view>
+ <view @click="retractReplyComment(index)" class="reply-op-item" style="margin-left: 50rpx;">鏀惰捣<text class="iconfont textSideIcon"></text></view>
+ </view>
+ <view class="reply-op" v-else-if="comment.replyTotalCount <= replyCommentQuery.pageNumber * replyCommentQuery.pageSize && comment.expandReply">
+ <view @click="retractReplyComment(index)" class="reply-op-item"><text class="line">鈥斺��</text>鏀惰捣<text class="iconfont textSideIcon"></text></view>
+ </view>
+ </view>
+ </scroll-view>
+ <view class="comment-input-area">
+ <input
+ ref="commentInput"
+ class="comment-input"
+ v-model="commentForm.commentContent"
+ :placeholder="commentForm.replyId ? `鍥炲 @${commentForm.replyUserNickname}` : '鍐欎笅浣犵殑璇勮...'"
+ placeholder-class="placeholder"
+ />
+ <button class="submit-btn" @click="submitComment" :disabled="!commentForm.commentContent.trim()">鍙戦��</button>
+ </view>
+ </view>
+ </uni-popup>
- </view>
+ <custom-tabbar bgColor="#333333" selected="index" selectedTextColor="#ffffff"></custom-tabbar>
+ </view>
</template>
<script>
- import {
- getHealthRecommendVideos,
- savePlayRecord,
- subscribe,
- getVideoComments,
- addVideoComment,
- thubmsUpComment,
- cancelThubmsUpComment
- } from "@/api/video.js";
- import {
- changeCollect
- } from "@/api/collect.js";
- export default {
- computed: {
- hasPlayTime() {
- return this.sliderFormatTime(this.progress > 0 ? this.duration * this.progress / 100 : 0);
+import TopBar from "@/components/TopBar.vue";
+import { getHealthRecommendVideos, savePlayRecord, subscribe, getVideoComments, addVideoComment, thubmsUpComment, cancelThubmsUpComment } from "@/api/video.js";
+import { changeCollect } from "@/api/collect.js";
+import { saveShare, saveShareClickRecord } from "@/api/share.js";
+import { silentLogin } from "@/api/connect.js";
+import { getUserInfo } from "@/api/members";
+import storage from "@/utils/storage.js";
+export default {
+ components: {TopBar},
+ computed: {
+ hasPlayTime() {
+ return this.sliderFormatTime(this.progress > 0 ? this.duration * this.progress / 100 : 0);
+ }
+ },
+ data() {
+ return {
+ currentImgIndex: 0, // 鎾斁鍒扮鍑犲紶鍥�--绱㈠紩
+ currentGoodsIndex: 0, // 鎾斁鍒扮鍑犱釜鍟嗗搧--绱㈠紩
+ currentTime: 0,
+ formartDuration: '',
+ duration: 0,
+ startX: 0,
+ progress: 0, // 瑙嗛杩涘害
+ startProgress : 0, // 寮�濮嬫粦鍔ㄦ椂鐨勮繘搴�
+ barLeft: 0, // 杩涘害鏉″乏杈圭晫浣嶇疆
+ barWidth: 0, // 杩涘害鏉″搴�
+ isDragging: false, // 鏄惁姝e湪鎷栧姩
+ processHidenTimer: null, // 杩涘害鏉¢殣钘忓畾鏃跺櫒
+ showProcess: false, // 鏄惁鏄剧ず杩涘害鏉�
+ videoNoMore: false, // 鏄惁杩樻湁鏇村瑙嗛
+ commentNoMore: false, // 鏄惁杩樻湁鏇村璇勮
+ commentQuery: {
+ pageNumber: 1,
+ pageSize: 5,
+ videoId: '',
+ masterCommentId: ''
+ },
+ replyCommentQuery: {
+ pageNumber: 1,
+ pageSize: 5,
+ videoId: '',
+ masterCommentId: ''
+ },
+ commentForm: { // 璇勮琛ㄥ崟鏁版嵁
+ id: '',
+ videoId: '',
+ commentContent: '',
+ replyId: '',
+ replyUserId: '',
+ replyUserNickname: '',
+ replyUserAvatar: '',
+ masterCommentId: null
+ },
+ comments: [], // 璇勮鍒楄〃
+ commentsTotal: 0, // 璇勮鎬绘潯鏁�
+ commentLoading: false, // 璇勮鍔犺浇鐘舵��
+ startHidenTime: 0, // 璁板綍鍒囨崲鑷冲叾瀹冮〉闈㈢殑鏃堕棿锛岀敤浜庤绠楄棰戣鐪嬫椂闂村噺鍘荤殑閮ㄥ垎
+ totalHidenTime: 0, // 鎬诲叡闅愯棌椤甸潰鐨勬椂闂�
+ startPauseTime: 0, // 寮�濮嬫殏鍋滅殑鏃堕棿
+ totalPauseTime: 0, // 鎬诲叡鏆傚仠鐨勬椂闂�
+ playRecord: {
+ videoId: null,
+ viewDuration: 0, // 杩欎釜瑙嗛鎬诲叡瑙傜湅浜嗗涔�
+ playAt: 0 ,// 杩欎釜瑙嗛鎾斁鍒板摢浜�
+ startPlayTime: 0 // 杩欎釜瑙嗛浠庝粈涔堟椂鍊欏紑濮嬫挱鏀剧殑
+ },
+ currentVideoIsPlaying: true, // 褰撳墠瑙嗛鏄惁姝e湪鎾斁
+ currentIndex: 0, // 褰撳墠鎾斁鐨勮棰戠储寮�
+ videoLoading: false, // 瑙嗛缂撳啿涓�
+ videoList: [], // 瑙嗛鍒楄〃鏁版嵁
+ videoBufferOffset: 0.1 ,// 瑙嗛棰勫姞杞藉弬鏁�
+ videoLiveOffset: 2, // 淇濈暀褰撳墠瑙嗛鍓嶅悗鍚勫灏戜釜瑙嗛涓婁笅鏂�
+ touchXY: { // 鐩戝惉宸︽粦鍙虫粦
+ startX: 0,
+ endX: 0,
+ startY: 0,
+ endY: 0
+ },
+ loading: false, // 鏄惁姝e湪鍔犺浇
+ videoQuery: {
+ pageNumber: 1,
+ pageSize: 10,
+ videoFrom: 'recommend'
+ }
+ }
+ },
+ onShow() {
+ // const token = storage.getAccessToken();
+ // if (! token) {
+ // this.wxSilentLogin(() => {
+ // this.loadVideos();
+ // })
+ // } else {
+ // this.loadVideos();
+ // }
+ // 濡傛灉瑙嗛鎸変笅鏆傚仠鍚庡垏鎹㈤〉闈㈠啀鍥炲埌椤甸潰鏃讹紝鍙畻鏆傚仠鏃堕棿锛堝洜涓烘殏鍋滄椂闂村拰绂诲紑椤甸潰鏃堕棿鏄噸澶嶇殑锛屽彧绠椾竴涓級
+ if(this.startHidenTime !== 0 && this.currentVideoIsPlaying) {
+ const duration = Date.now() - this.startHidenTime
+ this.totalHidenTime += duration
+ }
+ },
+ onHide() {
+ this.startHidenTime = Date.now()
+ },
+ onLoad(option) {
+ const token = storage.getAccessToken();
+ if (! token) {
+ this.wxSilentLogin(() => {
+ this.loadVideos();
+ // 鍒ゆ柇鏄笉鏄偣鍑诲垎浜摼鎺ヨ繘鏉ョ殑
+ if (option.userId && option.videoId) {
+ // 淇濆瓨鍒嗕韩鐐瑰嚮璁板綍
+ saveShareClickRecord({refId: option.videoId, shareUserId: option.userId})
+ }
+ })
+ } else {
+ this.loadVideos();
+ }
+ },
+ onShareAppMessage(e) {
+ const userInfo = storage.getUserInfo();
+ if(!userInfo) {
+ console.log("鏈櫥褰曚笉鑳藉垎浜�");
+ return
+ }
+ const videoInfo = e.target.dataset.obj;
+ // 淇濆瓨鍒嗕韩璁板綍
+ const data = {
+ shareType: 'video',
+ refId: videoInfo.id,
+ shareUser: userInfo.id
+ }
+ saveShare(data)
+ return {
+ title: videoInfo.title,
+ path: `/pages/tabbar/index/home?videoId=${videoInfo.id}&userId=${userInfo.id}`,
+ imageUrl: videoInfo.coverUrl
+ }
+ },
+ methods: {
+ topBarChange(titleObj) {
+ if (titleObj.index === 'home') {
+ uni.switchTab({
+ url: titleObj.pagePath
+ });
+ } else {
+ uni.redirectTo({
+ url: titleObj.pagePath
+ });
+ }
+ },
+ // 闈欓粯鐧诲綍
+ wxSilentLogin(callback) {
+ //鑾峰彇code
+ uni.login({
+ success: (codeRes) => {
+ if(codeRes.errMsg === "login:ok") {
+ // 闈欓粯鐧诲綍
+ silentLogin({code: codeRes.code}).then(res => {
+ storage.setAccessToken(res.data.data.accessToken);
+ storage.setRefreshToken(res.data.data.refreshToken);
+ //鑾峰彇鐢ㄦ埛淇℃伅
+ getUserInfo().then((user) => {
+ storage.setUserInfo(user.data.result);
+ storage.setHasLogin(true);
+ callback()
+ });
+ })
+ } else {
+ uni.showToast({
+ title: "绯荤粺寮傚父锛岃鑱旂郴绠$悊鍛橈紒"
+ })
+ }
+ },
+ });
+ },
+ // 鐐瑰嚮鍟嗗搧璺宠浆
+ jumpToPay(videoId) {
+ uni.navigateTo({
+ url: '/pages/video/video-goods-detail?videoId=' + videoId
+ });
+ },
+ // 杞挱鍥惧彉鍖�
+ imgChange(e) {
+ this.currentImgIndex = e.detail.current;
+ },
+ // 鍟嗗搧杞挱鍥惧彉鍖�
+ goodsChange(e) {
+ this.currentGoodsIndex = e.detail.current;
+ },
+ // 鑾峰彇杩涘害鏉$殑浣嶇疆鍜屽昂瀵�
+ getBarRect() {
+ const query = uni.createSelectorQuery().in(this);
+ query.select('#progressBar').boundingClientRect(rect => {
+ if (rect) {
+ this.barLeft = rect.left;
+ this.barWidth = rect.width;
+ }
+ }).exec();
+ },
+ // 璺宠浆涓汉涓婚〉
+ jumpToHomePage(authorId) {
+ uni.navigateTo({
+ url: "/pages/video/home-page?authorId=" + authorId
+ })
+ },
+ // 鍙栨秷鐐硅禐
+ async cancelThumbsUp(id, commentIndex, replyIndex) {
+ const data = {
+ refId: id,
+ thumbsUpType: 'video_comment'
+ }
+ cancelThubmsUpComment(data).then(res => {
+ if(replyIndex != null) {
+ this.comments[commentIndex].replies[replyIndex].hasThumbsUp = false;
+ this.comments[commentIndex].replies[replyIndex].thumbsUpNum -= 1;
+ } else {
+ this.comments[commentIndex].hasThumbsUp = false;
+ this.comments[commentIndex].thumbsUpNum -= 1;
+ }
+ })
+ },
+ // 璇勮鐐硅禐
+ async thubmsUp(id, commentIndex, replyIndex) {
+ const data = {
+ refId: id,
+ thumbsUpType: 'video_comment'
+ }
+ thubmsUpComment(data).then(res => {
+ if(replyIndex != null) {
+ this.comments[commentIndex].replies[replyIndex].hasThumbsUp = true;
+ this.comments[commentIndex].replies[replyIndex].thumbsUpNum += 1;
+ } else {
+ this.comments[commentIndex].hasThumbsUp = true;
+ this.comments[commentIndex].thumbsUpNum += 1;
+ }
+ })
+ },
+ // 鍔犺浇涓嬩竴椤靛洖澶�
+ loadNextPageReply(index) {
+ this.replyCommentQuery.pageNumber++;
+ getVideoComments(this.replyCommentQuery).then(res => {
+ this.comments[index].replies = [
+ ...this.comments[index].replies,
+ ...res.data.data.filter(
+ (newItem) => !this.comments[index].replies.some((oldItem) => oldItem.id === newItem.id)
+ ),
+ ];
+ })
+ },
+ // 鏀惰捣鍥炲
+ retractReplyComment(index) {
+ this.comments[index].expandReply = false;
+ this.comments[index].replies = [];
+ },
+ // 鍔犺浇鍥炲
+ loadRepliesPage(comment, index) {
+ this.replyCommentQuery.pageNumber = 1;
+ this.replyCommentQuery.masterCommentId = comment.id
+ getVideoComments(this.replyCommentQuery).then(res => {
+ this.comments[index].replies = res.data.data;
+ this.comments[index].expandReply = true;
+ })
+ },
+ resetCommentForm() {
+ const videoId = this.commentForm.videoId;
+ this.commentForm = { // 璇勮琛ㄥ崟鏁版嵁
+ id: '',
+ videoId: videoId,
+ commentContent: '',
+ replyId: '',
+ replyUserId: '',
+ replyUserNickname: '',
+ replyUserAvatar: '',
+ masterCommentId: null
}
},
- data() {
- return {
- currentImgIndex: 0, // 鎾斁鍒扮鍑犲紶鍥�--绱㈠紩
- currentTime: 0,
- formartDuration: [],
- duration: 0,
- startX: 0,
- progress: 0, // 瑙嗛杩涘害
- startProgress: 0, // 寮�濮嬫粦鍔ㄦ椂鐨勮繘搴�
- barLeft: 0, // 杩涘害鏉″乏杈圭晫浣嶇疆
- barWidth: 0, // 杩涘害鏉″搴�
- isDragging: false, // 鏄惁姝e湪鎷栧姩
- processHidenTimer: null, // 杩涘害鏉¢殣钘忓畾鏃跺櫒
- showProcess: false, // 鏄惁鏄剧ず杩涘害鏉�
- videoNoMore: false, // 鏄惁杩樻湁鏇村瑙嗛
- commentNoMore: false, // 鏄惁杩樻湁鏇村璇勮
- commentQuery: {
- pageNumber: 1,
- pageSize: 5,
- videoId: '',
- masterCommentId: ''
- },
- replyCommentQuery: {
- pageNumber: 1,
- pageSize: 5,
- videoId: '',
- masterCommentId: ''
- },
- commentForm: { // 璇勮琛ㄥ崟鏁版嵁
- id: '',
- videoId: '',
- commentContent: '',
- replyId: '',
- replyUserId: '',
- replyUserNickname: '',
- replyUserAvatar: '',
- masterCommentId: null
- },
- comments: [], // 璇勮鍒楄〃
- commentsTotal: 0, // 璇勮鎬绘潯鏁�
- commentLoading: false, // 璇勮鍔犺浇鐘舵��
- startHidenTime: 0, // 璁板綍鍒囨崲鑷冲叾瀹冮〉闈㈢殑鏃堕棿锛岀敤浜庤绠楄棰戣鐪嬫椂闂村噺鍘荤殑閮ㄥ垎
- totalHidenTime: 0, // 鎬诲叡闅愯棌椤甸潰鐨勬椂闂�
- startPauseTime: 0, // 寮�濮嬫殏鍋滅殑鏃堕棿
- totalPauseTime: 0, // 鎬诲叡鏆傚仠鐨勬椂闂�
- playRecord: {
- videoId: null,
- viewDuration: 0, // 杩欎釜瑙嗛鎬诲叡瑙傜湅浜嗗涔�
- playAt: 0, // 杩欎釜瑙嗛鎾斁鍒板摢浜�
- startPlayTime: 0 // 杩欎釜瑙嗛浠庝粈涔堟椂鍊欏紑濮嬫挱鏀剧殑
- },
- currentVideoIsPlaying: true, // 褰撳墠瑙嗛鏄惁姝e湪鎾斁
- isFullScreen: false,
- windowHeight: 0,
- currentIndex: 0, // 褰撳墠鎾斁鐨勮棰戠储寮�
- videoList: [
+ // 鍙栨秷鍥炲
+ cancelReply() {
+ this.resetCommentForm()
+ },
+ // 鎵撳紑鍥炲妗�
+ openReply(comment, reply = null) {
+ if(reply) {
+ comment = reply
+ }
+ this.commentForm.masterCommentId = comment.masterCommentId ? comment.masterCommentId : comment.id;
+ this.commentForm.replyId = comment.id;
+ this.commentForm.replyUserId = comment.userId;
+ this.commentForm.replyUserNickname = comment.userNickname;
+ this.commentForm.replyUserAvatar = comment.userAvatar;
+ // 鑷姩鑱氱劍杈撳叆妗�
+ this.$nextTick(() => {
+ const input = this.$refs.commentInput;
+ if (input) input.focus();
+ });
+ },
+ // 杩涘害鏉℃椂闂存牸寮忓寲 (00:00)
+ sliderFormatTime(seconds) {
+ const mins = Math.floor(seconds / 60);
+ const secs = Math.floor(seconds % 60);
+ return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
+ },
+ // 鏍煎紡鍖栨椂闂�
+ formatTime(time) {
+ const date = new Date(time);
+ const now = new Date();
+ const diff = Math.floor((now - date) / 1000); // 绉�
- ], // 瑙嗛鍒楄〃鏁版嵁
- videoContexts: [], // 瑙嗛涓婁笅鏂囧璞¢泦鍚�
- loading: false, // 鏄惁姝e湪鍔犺浇
- videoQuery: {
- pageNumber: 1,
- pageSize: 6,
- videoFrom: 'recommend',
- videoType: 'health'
- }
+ if (diff < 60) return '鍒氬垰';
+ if (diff < 3600) return `${Math.floor(diff / 60)}鍒嗛挓鍓峘;
+ if (diff < 86400) return `${Math.floor(diff / 3600)}灏忔椂鍓峘;
+
+ return `${date.getMonth() + 1}鏈�${date.getDate()}鏃;
+ },
+ // 鎻愪氦璇勮
+ async submitComment() {
+ if (!this.commentForm.commentContent.trim()) {
+ uni.showToast({
+ title: '璇勮鍐呭涓嶈兘涓虹┖',
+ icon: 'none'
+ });
+ return;
+ }
+ // 鍙戣〃璇勮
+ addVideoComment(this.commentForm).then(res => {
+ if(res.data.code === 200) {
+ this.resetCommentForm()
+
+ // 濡傛灉鏄瘎璁哄埆浜虹殑鍥炲锛岄偅涔堝氨灏嗚繖涓彂甯冨埌replies閲岄潰
+ if(res.data.data.replyId) {
+ for (const [index, item] of this.comments.entries()) {
+ if (item.id === res.data.data.replyId) {
+ item.replies.unshift(res.data.data);
+ // this.loadRepliesPage(item, index)
+ break; // 璺冲嚭寰幆
+ }
+ }
+ } else {
+ this.comments.unshift(res.data.data);
+ }
+ console.log("鏂板鍚�",this.comments);
+ uni.showToast({
+ title: '璇勮鎴愬姛'
+ });
+ // 褰撳墠瑙嗛璇勮鏁板姞涓�
+ this.commentsTotal += 1;
+ this.videoList[this.currentIndex].commentNum += 1;
+ } else {
+ uni.showToast({
+ title: res.data.msg,
+ icon: 'none'
+ });
+ }
+ }).catch(() => {
+ uni.showToast({
+ title: '璇勮澶辫触',
+ icon: 'none'
+ });
+ })
+ },
+ // 鍏抽棴璇勮寮圭獥
+ closeCommentPopup() {
+ this.$refs.commentPopup.close()
+ this.showCommentPopup = false;
+ this.comments = [];
+ this.resetCommentForm()
+ this.commentQuery.pageNumber = 1;
+ this.commentNoMore = false;
+ },
+ // 涓嬫粦璇勮鍖哄姞杞借瘎璁�
+ async getCommentPage() {
+ if(this.commentNoMore) {
+ return;
}
- },
- onShow() {
- this.loadVideos()
- // 濡傛灉瑙嗛鎸変笅鏆傚仠鍚庡垏鎹㈤〉闈㈠啀鍥炲埌椤甸潰鏃讹紝鍙畻鏆傚仠鏃堕棿锛堝洜涓烘殏鍋滄椂闂村拰绂诲紑椤甸潰鏃堕棿鏄噸澶嶇殑锛屽彧绠椾竴涓級
- if (this.startHidenTime !== 0 && this.currentVideoIsPlaying) {
- const duration = Date.now() - this.startHidenTime
- this.totalHidenTime += duration
- }
- },
- onHide() {
- this.startHidenTime = Date.now()
- },
- onLoad() {
- this.loadVideos();
- },
- onReady() {
- // 鍒濆鍖栬棰戜笂涓嬫枃
- this.initVideoContexts();
- },
- methods: {
- // 杞挱鍥惧彉鍖�
- imgChange(e) {
- this.currentImgIndex = e.detail.current;
- },
- // 鑾峰彇杩涘害鏉$殑浣嶇疆鍜屽昂瀵�
- getBarRect() {
- const query = uni.createSelectorQuery().in(this);
- query.select('#progressBar').boundingClientRect(rect => {
- if (rect) {
- this.barLeft = rect.left;
- this.barWidth = rect.width;
- }
- }).exec();
- },
- // 璺宠浆涓汉涓婚〉
- jumpToHomePage(authorId) {
- uni.navigateTo({
- url: "/pages/video/home-page?authorId=" + authorId
- })
- },
- // 鍙栨秷鐐硅禐
- async cancelThumbsUp(id, commentIndex, replyIndex) {
- const data = {
- refId: id,
- thumbsUpType: 'video_comment'
- }
- cancelThubmsUpComment(data).then(res => {
- if (replyIndex != null) {
- this.comments[commentIndex].replies[replyIndex].hasThumbsUp = false;
- this.comments[commentIndex].replies[replyIndex].thumbsUpNum -= 1;
- } else {
- this.comments[commentIndex].hasThumbsUp = false;
- this.comments[commentIndex].thumbsUpNum -= 1;
- }
- })
- },
- // 璇勮鐐硅禐
- async thubmsUp(id, commentIndex, replyIndex) {
- const data = {
- refId: id,
- thumbsUpType: 'video_comment'
- }
- thubmsUpComment(data).then(res => {
- if (replyIndex != null) {
- this.comments[commentIndex].replies[replyIndex].hasThumbsUp = true;
- this.comments[commentIndex].replies[replyIndex].thumbsUpNum += 1;
- } else {
- this.comments[commentIndex].hasThumbsUp = true;
- this.comments[commentIndex].thumbsUpNum += 1;
- }
- })
- },
- // 鍔犺浇涓嬩竴椤靛洖澶�
- loadNextPageReply(index) {
- this.replyCommentQuery.pageNumber++;
- getVideoComments(this.replyCommentQuery).then(res => {
- this.comments[index].replies = [
- ...this.comments[index].replies,
- ...res.data.data.filter(
- (newItem) => !this.comments[index].replies.some((oldItem) => oldItem.id === newItem
- .id)
- ),
+ getVideoComments(this.commentQuery).then(res => {
+ if(this.commentQuery.pageNumber === 1) {
+ this.comments = res.data.data
+ } else {
+ this.comments = [
+ ...this.comments,
+ ...res.data.data.filter(
+ (newItem) => !this.comments.some((oldItem) => oldItem.id === newItem.id)
+ ),
];
- })
- },
- // 鏀惰捣鍥炲
- retractReplyComment(index) {
- this.comments[index].expandReply = false;
- this.comments[index].replies = [];
- },
- // 鍔犺浇鍥炲
- loadRepliesPage(comment, index) {
- this.replyCommentQuery.pageNumber = 1;
- this.replyCommentQuery.masterCommentId = comment.id
- getVideoComments(this.replyCommentQuery).then(res => {
- this.comments[index].replies = res.data.data;
- this.comments[index].expandReply = true;
- })
- },
- resetCommentForm() {
- const videoId = this.commentForm.videoId;
- this.commentForm = { // 璇勮琛ㄥ崟鏁版嵁
- id: '',
- videoId: videoId,
- commentContent: '',
- replyId: '',
- replyUserId: '',
- replyUserNickname: '',
- replyUserAvatar: '',
- masterCommentId: null
}
- },
- // 鍙栨秷鍥炲
- cancelReply() {
- this.resetCommentForm()
- },
- // 鎵撳紑鍥炲妗�
- openReply(comment, reply = null) {
- if (reply) {
- comment = reply
+ if (res.data.data.length < this.commentQuery.pageSize) {
+ this.commentNoMore = true;
+ return;
}
- this.commentForm.masterCommentId = comment.masterCommentId ? comment.masterCommentId : comment.id;
- this.commentForm.replyId = comment.id;
- this.commentForm.replyUserId = comment.userId;
- this.commentForm.replyUserNickname = comment.userNickname;
- this.commentForm.replyUserAvatar = comment.userAvatar;
- // 鑷姩鑱氱劍杈撳叆妗�
- this.$nextTick(() => {
- const input = this.$refs.commentInput;
- if (input) input.focus();
+ this.commentQuery.pageNumber++;
+ })
+ },
+ // 鏄剧ず璇勮寮圭獥
+ async showComments(item) {
+ this.commentForm.videoId = item.id;
+ this.$refs.commentPopup.open();
+ this.commentLoading = true;
+ this.commentQuery.videoId = item.id
+ this.replyCommentQuery.videoId = item.id
+ // 棣栨鍔犺浇璇勮鍒嗛〉澶у皬澧炲姞涓�鍊嶏紝浠ヤ骇鐢熸粴鍔ㄦ潯锛屽悗缁彲瑙﹀彂
+ this.commentQuery.pageSize *= 2;
+ getVideoComments(this.commentQuery).then(res => {
+ this.commentsTotal = res.data.total;
+ this.comments = res.data.data;
+ this.commentQuery.pageNumber += 2;
+ this.commentQuery.pageSize /= 2;
+ }).catch(() => {
+ uni.showToast({
+ title: '鑾峰彇璇勮澶辫触',
+ icon: 'none'
+ });
+ }).finally(() => {
+ this.commentLoading = false;
+ })
+ },
+ // 鍏虫敞浣滆��
+ subscribeAuth(index, authorId) {
+ this.videoList.forEach(video => {
+ if(video.authorId === authorId) {
+ video.subscribeThisAuthor = true
+ }
+ })
+ subscribe(authorId).then(res => {
+ if(res.data.code === 200) {
+ uni.showToast({
+ title: '鍏虫敞鎴愬姛~',
+ icon: 'none'
});
- },
- // 杩涘害鏉℃椂闂存牸寮忓寲 (00:00)
- sliderFormatTime(seconds) {
- const mins = Math.floor(seconds / 60);
- const secs = Math.floor(seconds % 60);
- return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
- },
- // 鏍煎紡鍖栨椂闂�
- formatTime(time) {
- const date = new Date(time);
- const now = new Date();
- const diff = Math.floor((now - date) / 1000); // 绉�
-
- if (diff < 60) return '鍒氬垰';
- if (diff < 3600) return `${Math.floor(diff / 60)}鍒嗛挓鍓峘;
- if (diff < 86400) return `${Math.floor(diff / 3600)}灏忔椂鍓峘;
-
- return `${date.getMonth() + 1}鏈�${date.getDate()}鏃;
- },
- // 鎻愪氦璇勮
- async submitComment() {
- if (!this.commentForm.commentContent.trim()) {
- uni.showToast({
- title: '璇勮鍐呭涓嶈兘涓虹┖',
- icon: 'none'
- });
- return;
- }
- // 鍙戣〃璇勮
- addVideoComment(this.commentForm).then(res => {
- if (res.data.code === 200) {
- this.resetCommentForm()
-
- // 濡傛灉鏄瘎璁哄埆浜虹殑鍥炲锛岄偅涔堝氨灏嗚繖涓彂甯冨埌replies閲岄潰
- if (res.data.data.replyId) {
- for (const [index, item] of this.comments.entries()) {
- if (item.id === res.data.data.replyId) {
- item.replies.unshift(res.data.data);
- // this.loadRepliesPage(item, index)
- break; // 璺冲嚭寰幆
- }
- }
- } else {
- this.comments.unshift(res.data.data);
- }
- console.log("鏂板鍚�", this.comments);
- uni.showToast({
- title: '璇勮鎴愬姛'
- });
- // 褰撳墠瑙嗛璇勮鏁板姞涓�
- this.commentsTotal += 1;
- this.videoList[this.currentIndex].commentNum += 1;
- } else {
- uni.showToast({
- title: res.data.msg,
- icon: 'none'
- });
- }
- }).catch(() => {
- uni.showToast({
- title: '璇勮澶辫触',
- icon: 'none'
- });
- })
- },
- // 鍏抽棴璇勮寮圭獥
- closeCommentPopup() {
- this.$refs.commentPopup.close()
- this.showCommentPopup = false;
- this.comments = [];
- this.resetCommentForm()
- this.commentQuery.pageNumber = 1;
- this.commentNoMore = false;
- },
- // 涓嬫粦璇勮鍖哄姞杞借瘎璁�
- async getCommentPage() {
- if (this.commentNoMore) {
- return;
- }
- getVideoComments(this.commentQuery).then(res => {
- if (this.commentQuery.pageNumber === 1) {
- this.comments = res.data.data
- } else {
- this.comments = [
- ...this.comments,
- ...res.data.data.filter(
- (newItem) => !this.comments.some((oldItem) => oldItem.id === newItem.id)
- ),
- ];
- }
- if (res.data.data.length < this.commentQuery.pageSize) {
- this.commentNoMore = true;
- return;
- }
- this.commentQuery.pageNumber++;
- })
- },
- // 鏄剧ず璇勮寮圭獥
- async showComments(item) {
- this.commentForm.videoId = item.id;
- this.$refs.commentPopup.open();
- this.commentLoading = true;
- this.commentQuery.videoId = item.id
- this.replyCommentQuery.videoId = item.id
- // 棣栨鍔犺浇璇勮鍒嗛〉澶у皬澧炲姞涓�鍊嶏紝浠ヤ骇鐢熸粴鍔ㄦ潯锛屽悗缁彲瑙﹀彂
- this.commentQuery.pageSize *= 2;
- getVideoComments(this.commentQuery).then(res => {
- this.commentsTotal = res.data.total;
- this.comments = res.data.data;
- this.commentQuery.pageNumber += 2;
- this.commentQuery.pageSize /= 2;
- }).catch(() => {
- uni.showToast({
- title: '鑾峰彇璇勮澶辫触',
- icon: 'none'
- });
- }).finally(() => {
- this.commentLoading = false;
- })
- },
- // 鍏虫敞浣滆��
- subscribeAuth(index, authorId) {
+ } else {
this.videoList.forEach(video => {
- if (video.authorId === authorId) {
- video.subscribeThisAuthor = true
+ if(video.authorId === authorId) {
+ video.subscribeThisAuthor = false
}
})
- subscribe(authorId).then(res => {
- if (res.data.code === 200) {
- uni.showToast({
- title: '鍏虫敞鎴愬姛~',
- icon: 'none'
- });
- } else {
- this.videoList.forEach(video => {
- if (video.authorId === authorId) {
- video.subscribeThisAuthor = false
- }
- })
- }
- })
- },
- // 鍒濆鍖栬棰戜笂涓嬫枃
- initVideoContexts() {
- this.videoContexts = this.videoList.map((_, index) => {
- let videoContent = uni.createVideoContext(`video${index}`, this);
- return videoContent;
- });
- },
+ }
+ })
+ },
- // 鍔犺浇瑙嗛鏁版嵁
- async loadVideos() {
- if (this.loading || this.videoNoMore) return;
- this.loading = true;
+ // 鍔犺浇瑙嗛鏁版嵁
+ async loadVideos() {
+ if (this.loading || this.videoNoMore) return;
+ this.loading = true;
- getHealthRecommendVideos(this.videoQuery).then(res => {
- console.log(res, "瑙嗛鏁版嵁");
- if (this.videoQuery.pageNumber === 1) {
- this.videoList = res.data.data;
- } else {
- this.videoList = [
- ...this.videoList,
- ...res.data.data.filter(
- (newItem) => !this.videoList.some((oldItem) => oldItem.id === newItem.id)
- ),
- ];
- }
- this.$nextTick(() => {
- this.initVideoContexts();
- });
- this.loading = false;
- if (res.data.data.length < this.videoQuery.pageSize) {
- this.videoNoMore = true;
- return;
- }
- this.videoQuery.pageNumber++;
+ getHealthRecommendVideos(this.videoQuery).then(res => {
+ console.log(res, "瑙嗛鏁版嵁");
+ if (this.videoQuery.pageNumber === 1) {
+ this.videoList = res.data.data;
+ } else {
+ this.videoList = [
+ ...this.videoList,
+ ...res.data.data.filter(
+ (newItem) => !this.videoList.some((oldItem) => oldItem.id === newItem.id)
+ ),
+ ];
+ }
+ this.loading = false;
+ if(res.data.data.length < this.videoQuery.pageSize) {
+ this.videoNoMore = true;
+ return;
+ }
+ this.videoQuery.pageNumber++;
- })
- },
+ })
+ },
- // 婊戝姩鍒囨崲瑙嗛
- onSwiperChange(e) {
- // 濡傛灉瑙嗛澶勪簬鏆傚仠鐘舵�佸線涓嬪埛瑙嗛锛岄偅涔堥渶瑕佸啀璁$畻涓�娆℃殏鍋滄椂闂�
- if (!this.currentVideoIsPlaying) {
- if (this.startPauseTime !== 0) {
- const duration = Date.now() - this.startPauseTime
- this.totalPauseTime += duration
- }
- }
- // 淇濆瓨涓婁竴涓棰戠殑鎾斁璁板綍
- this.savePlayRecord()
- const oldIndex = this.currentIndex;
- this.currentIndex = e.detail.current;
-
- // 鏆傚仠涓婁竴涓棰�
- if (this.videoContexts[oldIndex]) {
- this.videoContexts[oldIndex].pause();
- }
-
- this.startPauseTime = 0;
- // 鎾斁褰撳墠瑙嗛
- if (this.videoContexts[this.currentIndex]) {
- this.videoContexts[this.currentIndex].play();
- }
- },
-
- // 鏀惰棌/鍙栨秷鏀惰棌
- toggleCollect(item, index) {
- let data = {
- refId: item.id,
- collectType: 'video'
- }
- const beforeCollected = item.collected
- const beforeCollectNum = item.collectNum
- if (item.collected) {
- this.videoList[index].collected = false
- this.videoList[index].collectNum -= 1
- } else {
- this.videoList[index].collected = true
- this.videoList[index].collectNum += 1
- }
- changeCollect(data).then(res => {
- if (res.data.code !== 200) {
- this.videoList[index].collected = beforeCollected
- this.videoList[index].collectNum = beforeCollectNum
- }
- })
- },
- // 鍗曞嚮灞忓箷锛氭殏鍋滄垨缁х画鎾斁
- togglePlay(index) {
- console.log("鍗曞嚮瑙嗛", index, this.videoContexts);
- if (this.currentVideoIsPlaying) {
- this.videoContexts[index].pause();
- } else {
- this.videoContexts[index].play();
- }
- },
- // 瑙嗛鎾斁浜嬩欢
- onPlay(id, index) {
- this.getBarRect()
- this.progress = 0
- console.log(id, index, "瑙﹀彂鎾斁");
- if (index === this.currentIndex) {
- this.currentVideoIsPlaying = true;
- } else {
- this.currentVideoIsPlaying = false;
- return
- }
- this.playRecord.videoId = id;
- // 娌″垵濮嬪寲鎵嶈祴鍊硷紝鍥犱负涓�涓棰戦噸澶嶆挱鏀緊nPlay浼氶噸澶嶈Е鍙�
- if (this.playRecord.startPlayTime === 0) {
- this.playRecord.startPlayTime = Date.now();
- }
- if (this.startPauseTime !== 0) {
- const duration = Date.now() - this.startPauseTime
- this.totalPauseTime += duration
- }
- },
-
- // 瑙嗛鏆傚仠浜嬩欢
- onPause(index) {
- console.log(index, "瑙﹀彂鏆傚仠");
- if (index === this.currentIndex) {
- this.currentVideoIsPlaying = false;
- } else {
- this.currentVideoIsPlaying = true;
- return
- }
- this.startPauseTime = Date.now()
- },
- // 瑙嗛缁撴潫浜嬩欢
- onEnded(index) {
- // this.currentVideoIsPlaying = false;
- },
-
- // 璁板綍鎾斁鏃堕暱
- onTimeUpdate(e) {
- this.playRecord.playAt = e.detail.currentTime;
-
- this.currentTime = e.detail.currentTime;
- this.progress = (e.detail.currentTime / this.duration) * 100
- },
- // 瑙︽懜寮�濮�
- handleTouchStart(e) {
- this.isDragging = true;
- this.showProcess = true;
- this.startProgress = this.progress; // 璁板綍寮�濮嬫椂鐨勮繘搴�
- this.startX = e.touches[0].pageX;
- console.log("璁板綍寮�濮嬫椂鐨勮繘搴�", this.startProgress);
- this.videoContexts[this.currentIndex].pause()
- // this.updateProgress(e);
- },
-
- // 瑙︽懜绉诲姩
- handleTouchMove(e) {
- if (!this.isDragging || !this.barWidth) return;
- clearTimeout(this.processHidenTimer)
- this.videoContexts[this.currentIndex].pause()
- this.updateProgress(e);
- },
-
- // 瑙︽懜缁撴潫
- handleTouchEnd() {
- this.isDragging = false;
- console.log("婊戝姩缁撴潫", this.duration * this.progress);
- this.videoContexts[this.currentIndex].seek(this.duration * this.progress / 100)
- this.videoContexts[this.currentIndex].play()
- this.processHidenTimer = setTimeout(() => {
- this.showProcess = false;
- }, 1000);
- },
-
- // 鏇存柊杩涘害
- updateProgress(e) {
- // 鑾峰彇褰撳墠瑙︽懜鐐筙鍧愭爣
- const currentX = e.touches[0].pageX;
-
- // 璁$畻婊戝姩璺濈(鍍忕礌)
- const deltaX = currentX - this.startX;
-
- // 灏嗗儚绱犺窛绂昏浆鎹负杩涘害澧為噺
- const deltaProgress = (deltaX / this.barWidth) * 100;
- console.log("杩涘害澧為噺", deltaProgress);
- // 璁$畻鏂拌繘搴� = 寮�濮嬫椂鐨勮繘搴� + 婊戝姩澧為噺
- let newProgress = this.startProgress + deltaProgress;
-
- // 闄愬埗鑼冨洿鍦�0-100涔嬮棿
- newProgress = Math.max(0, Math.min(100, newProgress));
-
- this.progress = newProgress;
- },
- // 鑾峰彇瑙嗛鎬绘椂闀�
- onLoadedMetadata(e) {
- this.duration = e.detail.duration;
- this.formartDuration.push(this.sliderFormatTime(this.duration));
- console.log("瑙嗛鎬绘椂闀�", this.duration);
- },
- // 淇濆瓨鎾斁璁板綍
- async savePlayRecord() {
- console.log(Date.now(), this.playRecord.startPlayTime, this.totalHidenTime);
-
- const data = {
- videoId: this.playRecord.videoId,
- viewDuration: Date.now() - this.playRecord.startPlayTime - this.totalHidenTime - this
- .totalPauseTime,
- playAt: this.playRecord.playAt
- }
- this.playRecord = {
- videoId: null,
- viewDuration: 0, // 杩欎釜瑙嗛鎬诲叡瑙傜湅浜嗗涔�
- playAt: 0, // 杩欎釜瑙嗛鎾斁鍒板摢浜�
- startPlayTime: 0 // 杩欎釜瑙嗛浠庝粈涔堟椂鍊欏紑濮嬫挱鏀剧殑
- }
- this.totalHidenTime = 0
- this.totalPauseTime = 0
- savePlayRecord(data)
+ // 婊戝姩鍒囨崲瑙嗛
+ onSwiperChange(e) {
+ this.videoLoading = false
+ // 濡傛灉瑙嗛澶勪簬鏆傚仠鐘舵�佸線涓嬪埛瑙嗛锛岄偅涔堥渶瑕佸啀璁$畻涓�娆℃殏鍋滄椂闂�
+ if(!this.currentVideoIsPlaying) {
+ if(this.startPauseTime !== 0) {
+ const duration = Date.now() - this.startPauseTime
+ this.totalPauseTime += duration
}
}
+ // 淇濆瓨涓婁竴涓棰戠殑鎾斁璁板綍
+ this.savePlayRecord()
+ const oldIndex = this.currentIndex;
+ this.currentIndex = e.detail.current;
+ const videoContext = uni.createVideoContext(`video${oldIndex}`, this);
+ // 鏆傚仠涓婁竴涓棰�
+ videoContext.pause();
+ this.startPauseTime = 0;
+
+ // 璁剧疆褰撳墠鎾斁瑙嗛鐨勬�绘椂闀�
+ this.duration = this.videoList[this.currentIndex].videoDuration;
+ this.formartDuration = this.sliderFormatTime(this.duration);
+
+ // 鎾斁褰撳墠瑙嗛
+ const videoContext1 = uni.createVideoContext(`video${this.currentIndex}`, this);
+ videoContext1.play()
+ // 濡傛灉鍓╀綑瑙嗛涓嶈冻锛岃Е鍙戣姹傝幏鍙栨洿澶氳棰�
+ if (this.videoList.length - 1 < this.currentIndex + this.videoLiveOffset) {
+ this.loadVideos()
+ }
+ },
+
+ // 寮�濮嬭Е鎽�
+ handleSwiperStart(e) {
+ console.log("寮�濮嬭Е鎽�", e);
+ this.touchXY.startX = e.touches[0].pageX
+ this.touchXY.startY = e.touches[0].pageY
+ },
+ // 瑙︽懜涓�
+ handleSwiperMove(e) {
+ this.touchXY.endX = e.touches[0].pageX
+ this.touchXY.endY = e.touches[0].pageY
+ },
+ // 缁撴潫瑙︽懜
+ handleSwiperEnd(item) {
+ // 闃叉婊戝姩婊氬姩鏉′篃瑙﹀彂璺宠浆
+ if (this.showProcess) {
+ return
+ }
+ const diffX = this.touchXY.endX - this.touchXY.startX
+ const diffY = this.touchXY.endY - this.touchXY.startY
+
+ // 鍒ゆ柇鏄惁鏄í鍚戞粦鍔紙X杞村彉鍖栧ぇ浜嶻杞村彉鍖栵級
+ if (Math.abs(diffX) > Math.abs(diffY)) {
+ if (diffX > 0) {
+ console.log('鍙虫粦')
+ if (item.goodsList && item.goodsList.length > 0) {
+ this.jumpToPay(item.id)
+ }
+ } else {
+ console.log('宸︽粦')
+ }
+ }
+ // 閲嶇疆鍧愭爣
+ this.touchXY = {
+ startX: 0,
+ endX: 0,
+ startY: 0,
+ endY: 0
+ }
+ },
+
+ // 鏀惰棌/鍙栨秷鏀惰棌
+ toggleCollect(item, index) {
+ let data = {
+ refId: item.id,
+ collectType: 'video'
+ }
+ const beforeCollected = item.collected
+ const beforeCollectNum = item.collectNum
+ if(item.collected) {
+ this.videoList[index].collected = false
+ this.videoList[index].collectNum -= 1
+ } else {
+ this.videoList[index].collected = true
+ this.videoList[index].collectNum += 1
+ }
+ changeCollect(data).then(res => {
+ if(res.data.code !== 200) {
+ this.videoList[index].collected = beforeCollected
+ this.videoList[index].collectNum = beforeCollectNum
+ }
+ })
+ },
+ // 鍗曞嚮灞忓箷锛氭殏鍋滄垨缁х画鎾斁
+ togglePlay(index) {
+ console.log("鍗曞嚮瑙嗛", index);
+ const videoContext = uni.createVideoContext(`video${index}`, this);
+ if(this.currentVideoIsPlaying) {
+ videoContext.pause();
+ } else {
+ videoContext.play();
+ }
+ },
+ // 瑙嗛鎾斁浜嬩欢
+ onPlay(id, index) {
+ if(index === this.currentIndex) {
+ this.currentVideoIsPlaying = true;
+ if(! this.duration) {
+ // 璁剧疆褰撳墠鎾斁瑙嗛鐨勬�绘椂闀�
+ this.duration = this.videoList[this.currentIndex].videoDuration;
+ this.formartDuration = this.sliderFormatTime(this.duration);
+ }
+ } else {
+ return
+ }
+ this.getBarRect()
+ this.progress = 0
+ console.log(id, index, "瑙﹀彂鎾斁");
+ this.playRecord.videoId = id;
+ // 娌″垵濮嬪寲鎵嶈祴鍊硷紝鍥犱负涓�涓棰戦噸澶嶆挱鏀緊nPlay浼氶噸澶嶈Е鍙�
+ if(this.playRecord.startPlayTime === 0) {
+ this.playRecord.startPlayTime = Date.now();
+ }
+ if(this.startPauseTime !== 0) {
+ const duration = Date.now() - this.startPauseTime
+ this.totalPauseTime += duration
+ }
+ this.videoLoading = false
+ },
+
+ // 瑙嗛鏆傚仠浜嬩欢
+ onPause(index) {
+ console.log(index, "瑙﹀彂鏆傚仠");
+ if(index === this.currentIndex) {
+ this.currentVideoIsPlaying = false;
+ this.startPauseTime = Date.now()
+ }
+ },
+ // 瑙嗛缁撴潫浜嬩欢
+ onEnded(index) {
+ // this.currentVideoIsPlaying = false;
+ },
+
+ // 璁板綍鎾斁鏃堕暱
+ onTimeUpdate(e) {
+ this.videoLoading = false
+ this.playRecord.playAt = e.detail.currentTime;
+
+ this.currentTime = e.detail.currentTime;
+ this.progress = (e.detail.currentTime / this.duration) * 100
+ },
+ // 瑙︽懜寮�濮�
+ handleTouchStart(e) {
+ this.isDragging = true;
+ this.showProcess = true;
+ this.startProgress = this.progress; // 璁板綍寮�濮嬫椂鐨勮繘搴�
+ this.startX = e.touches[0].pageX;
+ console.log("璁板綍寮�濮嬫椂鐨勮繘搴�", this.startProgress);
+ const videoContext = uni.createVideoContext(`video${this.currentIndex}`, this);
+ videoContext.pause()
+ // this.updateProgress(e);
+ },
+
+ // 瑙︽懜绉诲姩
+ handleTouchMove(e) {
+ if (!this.isDragging || !this.barWidth) return;
+ clearTimeout(this.processHidenTimer)
+ this.updateProgress(e);
+ },
+
+ // 瑙︽懜缁撴潫
+ handleTouchEnd() {
+ this.isDragging = false;
+ console.log("婊戝姩缁撴潫", this.duration * this.progress);
+ const videoContext = uni.createVideoContext(`video${this.currentIndex}`, this);
+ videoContext.seek(this.duration * this.progress / 100)
+ videoContext.play()
+ this.processHidenTimer = setTimeout(() => {
+ this.showProcess = false;
+ }, 1000);
+ },
+
+ // 鏇存柊杩涘害
+ updateProgress(e) {
+ // 鑾峰彇褰撳墠瑙︽懜鐐筙鍧愭爣
+ const currentX = e.touches[0].pageX;
+
+ // 璁$畻婊戝姩璺濈(鍍忕礌)
+ const deltaX = currentX - this.startX;
+
+ // 灏嗗儚绱犺窛绂昏浆鎹负杩涘害澧為噺
+ const deltaProgress = (deltaX / this.barWidth) * 100;
+ // 璁$畻鏂拌繘搴� = 寮�濮嬫椂鐨勮繘搴� + 婊戝姩澧為噺
+ let newProgress = this.startProgress + deltaProgress;
+
+ // 闄愬埗鑼冨洿鍦�0-100涔嬮棿
+ newProgress = Math.max(0, Math.min(100, newProgress));
+
+ this.progress = newProgress;
+ },
+ // 瑙嗛缂撳啿
+ videoWaiting(index) {
+ if (index === this.currentIndex) {
+ console.log("瑙嗛缂撳啿涓�傘�傘��");
+ this.videoLoading = true;
+ }
+ },
+ // 鑾峰彇瑙嗛鎬绘椂闀�
+ onLoadedMetadata(e) {
+ // this.duration = e.detail.duration;
+ // this.formartDuration = this.sliderFormatTime(this.duration);
+ // console.log("瑙嗛鎬绘椂闀�", this.duration);
+ },
+ // 淇濆瓨鎾斁璁板綍
+ async savePlayRecord() {
+ console.log(Date.now(), this.playRecord.startPlayTime, this.totalHidenTime);
+
+ const data = {
+ videoId: this.playRecord.videoId,
+ viewDuration: Date.now() - this.playRecord.startPlayTime - this.totalHidenTime - this.totalPauseTime,
+ playAt: this.playRecord.playAt
+ }
+ this.playRecord = {
+ videoId: null,
+ viewDuration: 0, // 杩欎釜瑙嗛鎬诲叡瑙傜湅浜嗗涔�
+ playAt: 0 ,// 杩欎釜瑙嗛鎾斁鍒板摢浜�
+ startPlayTime: 0 // 杩欎釜瑙嗛浠庝粈涔堟椂鍊欏紑濮嬫挱鏀剧殑
+ }
+ this.totalHidenTime = 0
+ this.totalPauseTime = 0
+ savePlayRecord(data)
}
+ }
+}
</script>
<style scoped>
::v-deep .custom-tabbar {
border-top: none !important;
}
-
.video-container {
- width: 100%;
- height: 100vh;
- background-color: #000;
+ width: 100%;
+ height: 100vh;
+ background-color: #000;
}
.video-swiper {
- width: 100%;
- height: calc(100% - 50px);
+ width: 100%;
+ height: calc(100% - 50px);
}
.video-item {
- width: 100%;
- height: 100%;
- object-fit: cover;
+ width: 100%;
+ height: 100%;
+ /* object-fit: cover; */
}
-
.play-icon {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- width: 45px;
- height: 45px;
- z-index: 10;
- opacity: 0.6;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 45px;
+ height: 45px;
+ z-index: 10;
+ opacity: 0.6;
}
.video-info {
- width: 70%;
- position: absolute;
- bottom: 70px;
- left: 20px;
- color: #f8f8f8;
- z-index: 10;
- letter-spacing: 1px;
+ width: 70%;
+ position: absolute;
+ bottom: 20px;
+ left: 20px;
+ color: #f8f8f8;
+ z-index: 10;
+ letter-spacing: 1px;
}
.action-buttons {
- position: absolute;
- right: 20px;
- bottom: 150px;
- display: flex;
- flex-direction: column;
- align-items: center;
- z-index: 10;
+ position: absolute;
+ right: 20px;
+ bottom: 150px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ z-index: 10;
}
.action-item {
- margin-bottom: 18px;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- color: #fff;
+ margin-bottom: 18px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ color: #fff;
}
-
.avatar-container {
- margin-bottom: 27px;
- position: relative;
- /* 涓虹粷瀵瑰畾浣嶇殑瀛愬厓绱犳彁渚涘畾浣嶄笂涓嬫枃 */
- width: 40px;
- height: 40px;
- display: inline-block;
- /* 浣垮鍣ㄦ牴鎹唴瀹硅皟鏁村ぇ灏� */
+ margin-bottom: 27px;
+ position: relative; /* 涓虹粷瀵瑰畾浣嶇殑瀛愬厓绱犳彁渚涘畾浣嶄笂涓嬫枃 */
+ width: 40px;
+ height: 40px;
+ display: inline-block; /* 浣垮鍣ㄦ牴鎹唴瀹硅皟鏁村ぇ灏� */
}
-
.avatar {
- border: 2px solid #FFFFFF;
- box-sizing: border-box;
- width: 100%;
- height: 100%;
- border-radius: 50%;
- /* 鍏抽敭灞炴�э紝璁剧疆涓�50%鍗冲彲瀹炵幇鍦嗗舰 */
- overflow: hidden;
- /* 纭繚鍥剧墖涓嶄細瓒呭嚭鍦嗗舰杈圭晫 */
- display: block;
+ border: 2px solid #FFFFFF;
+ box-sizing: border-box;
+ width: 100%;
+ height: 100%;
+ border-radius: 50%; /* 鍏抽敭灞炴�э紝璁剧疆涓�50%鍗冲彲瀹炵幇鍦嗗舰 */
+ overflow: hidden; /* 纭繚鍥剧墖涓嶄細瓒呭嚭鍦嗗舰杈圭晫 */
+ display: block;
}
-
.follow-icon {
- position: absolute;
- bottom: 0;
- /* 瀹氫綅鍒板簳閮� */
- left: 50%;
- /* 姘村钩灞呬腑寮�濮嬩綅缃� */
- transform: translate(-50%, 50%);
- /* 姘村钩灞呬腑骞跺悜涓嬬Щ鍔�50% */
+ position: absolute;
+ bottom: 0; /* 瀹氫綅鍒板簳閮� */
+ left: 50%; /* 姘村钩灞呬腑寮�濮嬩綅缃� */
+ transform: translate(-50%, 50%); /* 姘村钩灞呬腑骞跺悜涓嬬Щ鍔�50% */
- width: 18px;
- /* 鍥炬爣澶у皬 */
- height: 18px;
- background-color: #FF5A5F;
- /* 鍥炬爣鑳屾櫙鑹� */
- border-radius: 50%;
- display: flex;
- justify-content: center;
- align-items: center;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
- /* 杞诲井闃村奖 */
+ width: 18px; /* 鍥炬爣澶у皬 */
+ height: 18px;
+ background-color: #FF5A5F; /* 鍥炬爣鑳屾櫙鑹� */
+ border-radius: 50%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* 杞诲井闃村奖 */
}
-
.video-tag {
margin-left: 5px;
font-weight: bold;
color: #eeeeee;
}
-
.video-author {
font-size: 1.2em;
}
-
/* 鍟嗗搧閾炬帴鎮寕灞傛牱寮� */
.goods-link-warp {
position: absolute;
@@ -913,127 +1051,128 @@
color: #f8f8f8;
z-index: 10;
}
-
.goods-link {
- position: relative;
- margin: 20rpx 0;
- padding: 12rpx;
- background-color: rgba(255, 255, 255, 0.9);
- border-radius: 12rpx;
- box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
+ position: relative;
+ width: 450rpx;
+ margin: 20rpx 0;
+ padding: 12rpx;
+ background-color: rgba(255, 255, 255, 0.9);
+ border-radius: 12rpx;
+ box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
}
.goods-container {
- display: flex;
- align-items: center;
+ width: 100%;
+ display: flex;
+ align-items: center;
}
.goods-image {
- width: 120rpx;
- height: 120rpx;
- border-radius: 8rpx;
- margin-right: 20rpx;
+ width: 120rpx;
+ height: 120rpx;
+ border-radius: 8rpx;
+ margin-right: 20rpx;
}
.goods-info {
- flex: 1;
- display: flex;
- flex-direction: column;
- justify-content: center;
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
}
.goods-name {
- font-size: 28rpx;
- color: #333;
- font-weight: bold;
- display: -webkit-box;
- -webkit-line-clamp: 2;
- -webkit-box-orient: vertical;
- overflow: hidden;
- margin-bottom: 8rpx;
+ font-size: 28rpx;
+ color: #333;
+ font-weight: bold;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ margin-bottom: 8rpx;
+ width: 280rpx; /* 闇�瑕佹寚瀹氬搴� */
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
}
.price-section {
- display: flex;
- align-items: center;
- margin-bottom: 6rpx;
+ display: flex;
+ align-items: center;
+ margin-bottom: 6rpx;
}
.current-price {
- font-size: 32rpx;
- color: #ff2e4d;
- font-weight: bold;
- margin-right: 12rpx;
+ font-size: 32rpx;
+ color: #ff2e4d;
+ font-weight: bold;
+ margin-right: 12rpx;
}
.original-price {
- font-size: 28rpx;
- color: #999;
- text-decoration: line-through;
+ font-size: 28rpx;
+ color: #999;
+ text-decoration: line-through;
}
.sales-count {
- font-size: 22rpx;
- color: #999;
+ font-size: 22rpx;
+ color: #999;
}
.buy-button {
- background: linear-gradient(to right, #ff5a5f, #ff2e4d);
- color: white;
- padding: 10rpx 28rpx;
- border-radius: 20rpx;
- font-size: 26rpx;
- font-weight: bold;
+ background: linear-gradient(to right, #ff5a5f, #ff2e4d);
+ color: white;
+ padding: 10rpx 28rpx;
+ border-radius: 20rpx;
+ font-size: 26rpx;
+ font-weight: bold;
}
-
/* 璇勮寮圭獥鏍峰紡 */
.comment-popup {
- background-color: #fff;
- border-radius: 20rpx 20rpx 0 0;
- padding-bottom: env(safe-area-inset-bottom);
- height: 60vh;
- display: flex;
- flex-direction: column;
+ background-color: #fff;
+ border-radius: 20rpx 20rpx 0 0;
+ padding-bottom: env(safe-area-inset-bottom);
+ height: 60vh;
+ display: flex;
+ flex-direction: column;
}
.popup-header {
- padding: 30rpx;
- display: flex;
- justify-content: space-between;
- align-items: center;
- border-bottom: 1rpx solid #f5f5f5;
+ padding: 30rpx;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ border-bottom: 1rpx solid #f5f5f5;
}
.popup-title {
- font-size: 32rpx;
- font-weight: bold;
+ font-size: 32rpx;
+ font-weight: bold;
}
.close-icon {
- /* font-size: 36rpx; */
- color: #999;
+ /* font-size: 36rpx; */
+ color: #999;
}
.comment-list {
- flex: 1;
- padding: 0rpx 20rpx 20rpx 20rpx;
- box-sizing: border-box;
- height: calc(60vh - 260rpx);
+ flex: 1;
+ padding: 0rpx 20rpx 20rpx 20rpx;
+ box-sizing: border-box;
+ height: calc(60vh - 260rpx);
}
.comment-item {
- display: flex;
- flex-direction: column;
- padding: 10rpx 0 20rpx 0;
+ display: flex;
+ flex-direction: column;
+ padding: 10rpx 0 20rpx 0;
}
.comment-avatar {
- width: 70rpx;
- height: 70rpx;
- border-radius: 50%;
- margin-right: 10rpx;
+ width: 70rpx;
+ height: 70rpx;
+ border-radius: 50%;
+ margin-right: 10rpx;
}
-
.comment-reply-avatar {
width: 40rpx;
height: 40rpx;
@@ -1042,71 +1181,68 @@
}
.comment-content {
- flex: 1;
+ flex: 1;
}
.nickname {
- font-size: 28rpx;
- color: #666;
- display: block;
- margin-bottom: 10rpx;
+ font-size: 28rpx;
+ color: #666;
+ display: block;
+ margin-bottom: 10rpx;
}
.content {
- font-size: 28rpx;
- color: #333;
- display: block;
- margin-bottom: 10rpx;
+ font-size: 28rpx;
+ color: #333;
+ display: block;
+ margin-bottom: 10rpx;
}
.time {
- font-size: 28rpx;
- color: #999;
+ font-size: 28rpx;
+ color: #999;
}
.comment-input-area {
- display: flex;
- padding: 20rpx 30rpx;
- align-items: center;
+ display: flex;
+ padding: 20rpx 30rpx;
+ align-items: center;
}
.comment-input {
- flex: 1;
- background-color: #fff;
- height: 80rpx;
- border: 1px solid #dcdcdc;
- border-radius: 40rpx;
- padding: 0 30rpx;
- font-size: 28rpx;
+ flex: 1;
+ background-color: #fff;
+ height: 80rpx;
+ border: 1px solid #dcdcdc;
+ border-radius: 40rpx;
+ padding: 0 30rpx;
+ font-size: 28rpx;
}
.placeholder {
- color: #ccc;
+ color: #ccc;
}
.submit-btn {
- margin-left: 20rpx;
- background-color: #07c160;
- color: #fff;
- border-radius: 40rpx;
- padding: 0 30rpx;
- height: 80rpx;
- line-height: 80rpx;
- font-size: 28rpx;
+ margin-left: 20rpx;
+ background-color: #07c160;
+ color: #fff;
+ border-radius: 40rpx;
+ padding: 0 30rpx;
+ height: 80rpx;
+ line-height: 80rpx;
+ font-size: 28rpx;
}
- .loading,
- .empty {
- padding: 40rpx 0;
- text-align: center;
- color: #999;
+ .loading, .empty {
+ padding: 40rpx 0;
+ text-align: center;
+ color: #999;
}
-
.reply-list {
- margin-top: 20rpx;
- padding-left: 80rpx;
+ margin-top: 20rpx;
+ padding-left: 80rpx;
}
-
.reply-op {
margin-top: 10rpx;
padding-left: 80rpx;
@@ -1114,7 +1250,6 @@
font-size: 28rpx;
color: #333;
}
-
.reply-op-item {
display: flex;
align-items: center;
@@ -1122,125 +1257,128 @@
}
.reply-item {
- display: flex;
- margin-bottom: 20rpx;
+ display: flex;
+ margin-bottom: 20rpx;
}
.reply-content {
- flex: 1;
+ flex: 1;
}
.reply-to {
- color: #576b95;
- margin: 0 10rpx;
- font-size: 28rpx;
+ color: #576b95;
+ margin: 0 10rpx;
+ font-size: 28rpx;
}
-
.reply-title {
- display: flex;
- align-items: center;
- font-size: 28rpx;
- color: #333;
+ display: flex;
+ align-items: center;
+ font-size: 28rpx;
+ color: #333;
}
.cancel-reply {
- margin-left: 20rpx;
- color: #576b95;
- font-size: 28rpx;
- padding: 6rpx 12rpx;
- background: #f5f5f5;
- border-radius: 20rpx;
+ margin-left: 20rpx;
+ color: #576b95;
+ font-size: 28rpx;
+ padding: 6rpx 12rpx;
+ background: #f5f5f5;
+ border-radius: 20rpx;
}
-
.view-more-replies {
- color: #576b95;
- font-size: 28rpx;
- padding: 10rpx 0;
- padding-left: 80rpx;
+ color: #576b95;
+ font-size: 28rpx;
+ padding: 10rpx 0;
+ padding-left: 80rpx;
}
-
- .comment-footer,
- .reply-footer {
- display: flex;
- align-items: center;
- font-size: 28rpx;
- color: #999;
+ .comment-footer, .reply-footer {
+ display: flex;
+ align-items: center;
+ font-size: 28rpx;
+ color: #999;
}
-
.reply-btu {
margin-left: 30rpx;
}
-
.thumbs-up {
position: absolute;
right: 20rpx;
font-size: 32rpx;
width: 120rpx;
}
-
.textSideIcon {
font-size: 36rpx;
margin-left: 5rpx;
}
-
.line {
margin-right: 10rpx;
color: #cccccc;
}
-
.thumbs-num {
margin-left: 4rpx;
}
-
.container {
- display: flex;
- flex-direction: column;
- align-items: center;
- position: absolute;
- bottom: 0;
- width: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ position: absolute;
+ bottom: 0;
+ width: 100%;
}
.progress-bar {
- position: relative;
- width: 100%;
- height: 16px;
- background-color: #eee;
- overflow: hidden;
+ position: relative;
+ width: 100%;
+ height: 16px;
+ background-color: #eee;
+ overflow: hidden;
}
.progress-fill {
- position: absolute;
- left: 0;
- top: 0;
- height: 100%;
- background-color: lightgray;
- transition: width 0.1s;
+ position: absolute;
+ left: 0;
+ top: 0;
+ height: 100%;
+ background-color: lightgray;
+ transition: width 0.1s;
}
-
.process-warp {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
-
.progress-text {
- margin-top: 10px;
- font-size: 14px;
- color: #666;
+ margin-top: 10px;
+ font-size: 14px;
+ color: #666;
}
-
.swiper-box {
- width: 100%;
- height: 1400rpx;
+ width: 100%;
+ height: 1400rpx;
}
-
.swiper-item {
- display: flex;
- justify-content: center;
- align-items: center;
- width: 100%;
- height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ height: 100%;
}
-</style>
\ No newline at end of file
+ .custom-share-btn {
+ font-size: unset;
+ background: none;
+ padding: 0;
+ margin: 0;
+ line-height: normal;
+ border: none;
+ }
+ .custom-share-btn::after {
+ border: none;
+ }
+ .topBar {
+ position: fixed;
+ top: 20rpx;
+ left: 20rpx;
+ z-index: 1000
+ }
+</style>
diff --git a/pages/kitchen/KitchenVideo.vue b/pages/kitchen/KitchenVideo.vue
index b982f72..a01aae6 100644
--- a/pages/kitchen/KitchenVideo.vue
+++ b/pages/kitchen/KitchenVideo.vue
@@ -1,1336 +1,1430 @@
<template>
- <view class="video-container">
- <!-- 瑙嗛鍒楄〃 -->
- <swiper class="video-swiper" vertical circular :current="currentIndex" @change="onSwiperChange">
- <view class="showLeft" @click="showDrawer('showLeft')" v-if="!showLeft">
- <uni-icons type="right" size="30"></uni-icons>
- </view>
- <swiper-item v-for="(item, index) in videoList" :key="item.id">
- <view style="width: 100%;height: 100%;" v-if="item.videoContentType === 'video'">
- <!-- 鎾斁鎸夐挳锛堜粎褰撹棰戞殏鍋滄椂鏄剧ず锛� -->
- <view class="play-icon" @click="togglePlay(index)" v-if="!currentVideoIsPlaying">
- <image src="/static/video/play.png" style="width: 45px;height: 45px" mode="aspectFit"></image>
- </view>
- <video :id="'video'+index" :ref="'video'+index" :src="item.videoUrl"
- :autoplay="currentIndex === index" :controls="false" :loop="true" :object-fit="item.objectFit"
- :enable-progress-gesture="false" class="video-item" @play="onPlay(item.id, index)"
- @pause="onPause(index)" @ended="onEnded(index)" @click="togglePlay(index)"
- @timeupdate="onTimeUpdate($event)" @loadedmetadata="onLoadedMetadata($event)"></video>
- <!-- 鑷畾涔夋帶鍒舵潯 -->
- <view @touchstart="handleTouchStart" @touchmove="handleTouchMove" @touchend="handleTouchEnd"
- class="container">
- <!-- 杩涘害鏉� - 鏁翠釜鍖哄煙鍙嫋鍔� -->
- <view class="process-warp" :style="{ opacity: showProcess ? 1 : 0 }">
- <!-- 鏄剧ず褰撳墠杩涘害 -->
- <view class="progress-text">{{ hasPlayTime }}/{{formartDuration[index]}}</view>
- <view class="progress-bar" id="progressBar">
+ <view class="video-container">
+ <!-- 瑙嗛鍔犺浇 -->
+ <zero-loading v-show="videoLoading" type="circle" color="#0ebd57" text=""></zero-loading>
+ <view class="showLeft" @click="showDrawer('showLeft')" v-if="!showLeft">
+ <uni-icons type="right" size="30"></uni-icons>
+ </view>
+ <!-- 瑙嗛鍒楄〃 -->
+ <swiper v-if="videoList.length > 0"
+ class="video-swiper"
+ vertical
+ :current="currentIndex"
+ @change="onSwiperChange"
+ :duration="250"
+ easing-function="linear"
+ >
- <!-- 宸插~鍏呴儴鍒� -->
- <view class="progress-fill" :style="{ width: progress + '%' }"></view>
- </view>
- </view>
- </view>
- </view>
- <view style="width: 100%; height: 100%;" v-else-if="item.videoContentType === 'img'">
- <uni-swiper-dot :info="item.imgs" :current="currentImgIndex" mode="round"
- style="width: 100%;height: 100%;display: flex;justify-content: center;align-items: center;"
- :dots-styles="{width: 24, bottom: 24,selectedBackgroundColor: 'green', backgroundColor: 'gray'}">
- <swiper class="swiper-box" @change="imgChange" :autoplay="true" :interval="3000">
- <swiper-item v-for="img in item.imgs" :key="img">
- <view class="swiper-item">
- <!-- 璋冩暣 image 鏍峰紡锛屼娇鍏跺眳涓笖鎸夋瘮渚嬬缉鏀� -->
- <image :src="img" mode="aspectFit"
- style="width: 100%; height: 100%; display: block; margin: 0 auto;"></image>
- </view>
- </swiper-item>
- </swiper>
- </uni-swiper-dot>
- </view>
+ <swiper-item
+ v-for="(item, index) in videoList"
+ :key="item.id"
+ @touchstart="handleSwiperStart"
+ @touchmove="handleSwiperMove"
+ @touchend="handleSwiperEnd(item)"
+ >
+ <view style="width: 100%;height: 100%;" v-if="item.videoContentType === 'video'">
+ <!-- 鎾斁鎸夐挳锛堜粎褰撹棰戞殏鍋滄椂鏄剧ず锛� -->
+ <view
+ class="play-icon"
+ @click="togglePlay(index)"
+ v-show="!currentVideoIsPlaying"
+ >
+ <image src="/static/video/play.png" style="width: 45px;height: 45px" mode="aspectFit"></image>
+ </view>
+ <video
+ v-if="index >= currentIndex - videoLiveOffset && index <= currentIndex + videoLiveOffset"
+ :id="'video'+index"
+ :ref="'video'+index"
+ :src="item.videoUrl"
+ :autoplay="index === currentIndex"
+ :controls="false"
+ :loop="true"
+ :object-fit="item.objectFit"
+ :enable-progress-gesture="false"
+ :show-center-play-btn="false"
+ class="video-item"
+ @play="onPlay(item.id, index)"
+ @pause="onPause(index)"
+ @ended="onEnded(index)"
+ @click="togglePlay(index)"
+ @timeupdate="onTimeUpdate($event)"
+ @loadedmetadata="onLoadedMetadata($event)"
+ @waiting="videoWaiting(index)"
+ ></video>
+ <!-- 鑷畾涔夋帶鍒舵潯 -->
+ <view
+ @touchstart.stop="handleTouchStart"
+ @touchmove.stop="handleTouchMove"
+ @touchend.stop="handleTouchEnd"
+ class="container">
+ <!-- 杩涘害鏉� - 鏁翠釜鍖哄煙鍙嫋鍔� -->
+ <view class="process-warp" :style="{ opacity: showProcess ? 1 : 0 }">
+ <!-- 鏄剧ず褰撳墠杩涘害 -->
+ <view class="progress-text">{{ hasPlayTime }}/{{formartDuration}}</view>
+ <view
+ class="progress-bar"
+ id="progressBar"
+ >
+
+ <!-- 宸插~鍏呴儴鍒� -->
+ <view class="progress-fill" :style="{ width: progress + '%' }"></view>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view style="width: 100%; height: 100%;" v-else-if="item.videoContentType === 'img'">
+ <uni-swiper-dot
+ :info="item.imgs"
+ :current="currentImgIndex"
+ mode="round"
+ style="width: 100%;height: 100%;display: flex;justify-content: center;align-items: center;"
+ :dots-styles="{width: 24, bottom: 24,selectedBackgroundColor: 'green', backgroundColor: 'gray'}"
+ >
+ <swiper class="swiper-box" @change="imgChange" :autoplay="true" :interval="3000">
+ <swiper-item v-for="img in item.imgs" :key="img">
+ <view class="swiper-item">
+ <!-- 璋冩暣 image 鏍峰紡锛屼娇鍏跺眳涓笖鎸夋瘮渚嬬缉鏀� -->
+ <image
+ :src="img"
+ mode="aspectFit"
+ style="width: 100%; height: 100%; display: block; margin: 0 auto;"
+ ></image>
+ </view>
+ </swiper-item>
+ </swiper>
+ </uni-swiper-dot>
+ </view>
- <!-- 鎮寕鍟嗗搧閾炬帴灞� -->
- <view class="goods-link-warp" v-if="false">
- <view class="goods-link">
- <view class="goods-container">
- <!-- 鍟嗗搧鍥剧墖 -->
- <image class="goods-image" :src="item.goods.imageUrl" mode="aspectFill"></image>
+ <!-- 鎮寕鍟嗗搧閾炬帴灞� -->
+ <view class="goods-link-warp" v-if="item.goodsList.length > 0">
+ <view class="goods-link">
+ <swiper @change="goodsChange" :autoplay="true" :interval="4000" style="height: 120rpx;">
+ <swiper-item v-for="goods in item.goodsList" :key="goods.goodsId">
+ <view class="goods-container" @click="jumpToPay(item.id)">
+ <!-- 鍟嗗搧鍥剧墖 -->
+ <image class="goods-image" :src="goods.thumbnail" mode="aspectFill"></image>
- <!-- 鍟嗗搧淇℃伅 -->
- <view class="goods-info">
- <text class="goods-name">{{item.goods.name}}</text>
- <view class="price-section">
- <text class="current-price">楼{{item.goods.price}}</text>
- <text class="original-price"
- v-if="item.goods.originalPrice">楼{{item.goods.originalPrice}}</text>
- </view>
- <text class="sales-count">{{item.goods.saleNum}}浜哄凡璐�</text>
- </view>
-
- <!-- 璐拱鎸夐挳 -->
- <view class="buy-button">
- <text>璐拱</text>
- </view>
- </view>
- </view>
- </view>
+ <!-- 鍟嗗搧淇℃伅 -->
+ <view class="goods-info">
+ <text class="goods-name">{{goods.goodsName}}</text>
+ <view class="price-section">
+ <text class="current-price">楼{{goods.price}}</text>
+ <text class="original-price" v-if="goods.originalPrice">楼{{goods.originalPrice}}</text>
+ </view>
+ </view>
+ </view>
+ </swiper-item>
+ </swiper>
+ </view>
+ </view>
- <!-- 瑙嗛淇℃伅灞� -->
- <view class="video-info">
- <view>
- <text class="video-author">@{{item.authorName}}</text>
- </view>
- <view style="width: 100%;word-wrap: break-word;white-space: normal;overflow-wrap: break-word;">
- <text class="video-title">{{item.title}}</text>
- <text class="video-tag" v-for="(tag, index) in item.tagList"
- :key="tag.id">#{{tag.tagName}}</text>
- </view>
- </view>
+ <!-- 瑙嗛淇℃伅灞� -->
+ <view class="video-info">
+ <view>
+ <text class="video-author">@{{item.authorName}}</text>
+ </view>
+ <view style="width: 100%;word-wrap: break-word;white-space: normal;overflow-wrap: break-word;">
+ <text class="video-title">{{item.title}}</text>
+ <text class="video-tag" v-for="(tag, index) in item.tagList" :key="tag.id">#{{tag.tagName}}</text>
+ </view>
+ </view>
- <!-- 鍙充晶浜掑姩鎸夐挳 -->
- <view class="action-buttons" v-if="false">
- <view class="avatar-container">
- <image class="avatar" @click="jumpToHomePage(item.authorId)" :src="item.authorAvatar"
- mode="aspectFill"></image>
- <!-- 鍏虫敞鍥炬爣 - 浣跨敤缁濆瀹氫綅 -->
- <view v-if="!item.subscribeThisAuthor" class="follow-icon"
- @click="subscribeAuth(index, item.authorId)">
- <text class="iconfont"></text>
- </view>
- </view>
- <view class="action-item" @click="toggleCollect(item, index)">
- <text class="iconfont" v-if="item.collected"></text>
- <text class="iconfont" v-else></text>
- <text style="font-size: 10px;font-weight: lighter;">{{item.collectNum}}</text>
- </view>
- <view class="action-item" @click="showComments(item)">
- <text class="iconfont"></text>
- <text style="font-size: 10px;font-weight: lighter;">{{item.commentNum}}</text>
- </view>
- </view>
+ <!-- 鍙充晶浜掑姩鎸夐挳 -->
+ <view class="action-buttons" v-if="false">
+ <view class="avatar-container">
+ <image class="avatar" @click="jumpToHomePage(item.authorId)" :src="item.authorAvatar" mode="aspectFill"></image>
+ <!-- 鍏虫敞鍥炬爣 - 浣跨敤缁濆瀹氫綅 -->
+ <view v-if="!item.subscribeThisAuthor" class="follow-icon" @click="subscribeAuth(index, item.authorId)">
+ <text class="iconfont"></text>
+ </view>
+ </view>
+ <view class="action-item" @click="toggleCollect(item, index)">
+ <text class="iconfont" v-if="item.collected"></text>
+ <text class="iconfont" v-else></text>
+ <text style="font-size: 10px;font-weight: lighter;">{{item.collectNum}}</text>
+ </view>
+ <view class="action-item" @click="showComments(item)">
+ <text class="iconfont"></text>
+ <text style="font-size: 10px;font-weight: lighter;">{{item.commentNum}}</text>
+ </view>
+ <view class="action-item">
+ <button open-type="share" class="custom-share-btn" :data-obj="item">
+ <text class="iconfont"></text>
+ </button>
- </swiper-item>
- </swiper>
+ </view>
+ </view>
- <!-- 璇勮寮圭獥 -->
- <uni-popup ref="commentPopup" type="bottom" :is-mask-click="true" @maskClick="closeCommentPopup">
- <view class="comment-popup">
- <view class="popup-header">
- <text class="popup-title" v-if="!commentForm.replyId">璇勮({{commentsTotal}})</text>
- <view class="reply-title" v-else>
- <text>鍥炲 @{{commentForm.replyUserNickname}}</text>
- <text class="cancel-reply" @click="cancelReply">鍙栨秷</text>
- </view>
- <text class="iconfont close-icon" @click="closeCommentPopup"></text>
- </view>
+ </swiper-item>
+ </swiper>
+ <!-- 璇勮寮圭獥 -->
+ <uni-popup ref="commentPopup" type="bottom" :is-mask-click="true" @maskClick="closeCommentPopup">
+ <view class="comment-popup">
+ <view class="popup-header">
+ <text class="popup-title" v-if="!commentForm.replyId">璇勮({{commentsTotal}})</text>
+ <view class="reply-title" v-else>
+ <text>鍥炲 @{{commentForm.replyUserNickname}}</text>
+ <text class="cancel-reply" @click="cancelReply">鍙栨秷</text>
+ </view>
+ <text class="iconfont close-icon" @click="closeCommentPopup"></text>
+ </view>
- <scroll-view class="comment-list" scroll-y :show-scrollbar="false" @scrolltolower="getCommentPage">
- <view v-if="commentLoading" class="loading">
- <uni-load-more status="loading"></uni-load-more>
- </view>
+ <scroll-view class="comment-list" scroll-y :show-scrollbar="false" @scrolltolower="getCommentPage">
+ <view v-if="commentLoading" class="loading">
+ <uni-load-more status="loading"></uni-load-more>
+ </view>
- <view v-else-if="comments.length === 0" class="empty">
- 鏆傛棤璇勮锛屽揩鏉ュ彂琛ㄧ涓�鏉¤瘎璁哄惂~
- </view>
+ <view v-else-if="comments.length === 0" class="empty">
+ 鏆傛棤璇勮锛屽揩鏉ュ彂琛ㄧ涓�鏉¤瘎璁哄惂~
+ </view>
- <view v-else class="comment-item" v-for="(comment, index) in comments" :key="comment.id">
- <view style="display: flex;">
- <image class="comment-avatar" :src="comment.userAvatar || '/static/default-avatar.png'">
- </image>
- <view class="comment-content">
- <text class="nickname">{{comment.userNickname}}</text>
- <text class="content">{{comment.commentContent}}</text>
- <view style="position: relative;">
- <text class="time">{{formatTime(comment.createTime)}}</text>
- <text @click="openReply(comment)" class="reply-btu time">鍥炲</text>
- <text v-if="!comment.hasThumbsUp" class="thumbs-up time iconfont"
- @click="thubmsUp(comment.id, index, null)"><text
- v-show="comment.thumbsUpNum > 0"
- class="thumbs-num">{{comment.thumbsUpNum}}</text></text>
- <text v-else class="thumbs-up time iconfont"
- @click="cancelThumbsUp(comment.id, index, null)"><text
- v-show="comment.thumbsUpNum > 0"
- class="thumbs-num">{{comment.thumbsUpNum}}</text></text>
- </view>
- </view>
- </view>
- <!-- 鍥炲鍒楄〃 -->
- <view class="reply-list" v-if="comment.replies && comment.replies.length > 0">
- <view class="reply-item" v-for="(reply, replyIndex) in comment.replies" :key="reply.id">
- <view class="reply-content">
- <view style="display: flex;">
- <image class="comment-reply-avatar"
- :src="reply.replyUserAvatar || '/static/default-avatar.png'"></image>
- <text class="nickname">{{reply.userNickname}}</text>
- <text v-if="reply.replyUserId && reply.masterCommentId !== reply.replyId"
- class="reply-to"><text style="margin-right: 10rpx;font-size: 28rpx;"
- class="iconfont"></text>{{reply.replyUserNickname}}</text>
- </view>
- <text class="content">{{reply.commentContent}}</text>
- <view class="reply-footer">
- <text class="time">{{formatTime(reply.createTime)}}</text>
- <text @click="openReply(comment, reply)" class="reply-btu time">鍥炲</text>
- <text v-if="!reply.hasThumbsUp" class="thumbs-up time iconfont"
- @click="thubmsUp(reply.id, index, replyIndex)"><text
- v-show="reply.thumbsUpNum > 0"
- class="thumbs-num">{{reply.thumbsUpNum}}</text></text>
- <text v-else class="thumbs-up time iconfont"
- @click="cancelThumbsUp(reply.id, index, replyIndex)"><text
- v-show="reply.thumbsUpNum > 0"
- class="thumbs-num">{{reply.thumbsUpNum}}</text></text>
- </view>
- </view>
- </view>
- </view>
- <view class="view-more-replies" v-if="comment.replyTotalCount > 0 && !comment.expandReply"
- @click="loadRepliesPage(comment, index)">
- <text class="line">鈥斺��</text>灞曞紑{{comment.replyTotalCount}}鏉″洖澶� 鈫�
- </view>
- <view class="reply-op"
- v-if="comment.replyTotalCount > replyCommentQuery.pageNumber * replyCommentQuery.pageSize && comment.expandReply">
- <view @click="loadNextPageReply(index)" class="reply-op-item"><text
- class="line">鈥斺��</text>灞曞紑鏇村<text class="iconfont textSideIcon"></text></view>
- <view @click="retractReplyComment(index)" class="reply-op-item" style="margin-left: 50rpx;">
- 鏀惰捣<text class="iconfont textSideIcon"></text></view>
- </view>
- <view class="reply-op"
- v-else-if="comment.replyTotalCount <= replyCommentQuery.pageNumber * replyCommentQuery.pageSize && comment.expandReply">
- <view @click="retractReplyComment(index)" class="reply-op-item"><text
- class="line">鈥斺��</text>鏀惰捣<text class="iconfont textSideIcon"></text></view>
- </view>
- </view>
- </scroll-view>
- <view class="comment-input-area">
- <input ref="commentInput" class="comment-input" v-model="commentForm.commentContent"
- :placeholder="commentForm.replyId ? `鍥炲 @${commentForm.replyUserNickname}` : '鍐欎笅浣犵殑璇勮...'"
- placeholder-class="placeholder" />
- <button class="submit-btn" @click="submitComment"
- :disabled="!commentForm.commentContent.trim()">鍙戦��</button>
- </view>
- </view>
- </uni-popup>
- <uni-drawer ref="showLeft" mode="left" width="120" :cus-style="true" height="93vh"
- @change="change($event,'showLeft')" class="navigationLeft">
- <scroll-view class="typeNavigation" :scroll-y="true" :show-scrollbar="false">
- <view class="typeNavigationItem" :class="{typeNavigationItemCheck:currentCategort ==item.id}"
- @click="chooseCategory(item.id)" v-for="item in categoryList" :key="item.id">
- {{item.typeName}}
- </view>
- </scroll-view>
- </uni-drawer>
-
- </view>
+ <view v-else class="comment-item" v-for="(comment, index) in comments" :key="comment.id">
+ <view style="display: flex;">
+ <image class="comment-avatar" :src="comment.userAvatar || '/static/default-avatar.png'"></image>
+ <view class="comment-content">
+ <text class="nickname">{{comment.userNickname}}</text>
+ <text class="content">{{comment.commentContent}}</text>
+ <view style="position: relative;">
+ <text class="time">{{formatTime(comment.createTime)}}</text>
+ <text @click="openReply(comment)" class="reply-btu time">鍥炲</text>
+ <text v-if="!comment.hasThumbsUp" class="thumbs-up time iconfont" @click="thubmsUp(comment.id, index, null)"><text v-show="comment.thumbsUpNum > 0" class="thumbs-num">{{comment.thumbsUpNum}}</text></text>
+ <text v-else class="thumbs-up time iconfont" @click="cancelThumbsUp(comment.id, index, null)"><text v-show="comment.thumbsUpNum > 0" class="thumbs-num">{{comment.thumbsUpNum}}</text></text>
+ </view>
+ </view>
+ </view>
+ <!-- 鍥炲鍒楄〃 -->
+ <view class="reply-list" v-if="comment.replies && comment.replies.length > 0">
+ <view class="reply-item" v-for="(reply, replyIndex) in comment.replies" :key="reply.id">
+ <view class="reply-content">
+ <view style="display: flex;">
+ <image class="comment-reply-avatar" :src="reply.replyUserAvatar || '/static/default-avatar.png'"></image>
+ <text class="nickname">{{reply.userNickname}}</text>
+ <text v-if="reply.replyUserId && reply.masterCommentId !== reply.replyId" class="reply-to"><text style="margin-right: 10rpx;font-size: 28rpx;" class="iconfont"></text>{{reply.replyUserNickname}}</text>
+ </view>
+ <text class="content">{{reply.commentContent}}</text>
+ <view class="reply-footer">
+ <text class="time">{{formatTime(reply.createTime)}}</text>
+ <text @click="openReply(comment, reply)" class="reply-btu time">鍥炲</text>
+ <text v-if="!reply.hasThumbsUp" class="thumbs-up time iconfont" @click="thubmsUp(reply.id, index, replyIndex)"><text v-show="reply.thumbsUpNum > 0" class="thumbs-num">{{reply.thumbsUpNum}}</text></text>
+ <text v-else class="thumbs-up time iconfont" @click="cancelThumbsUp(reply.id, index, replyIndex)"><text v-show="reply.thumbsUpNum > 0" class="thumbs-num">{{reply.thumbsUpNum}}</text></text>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view class="view-more-replies" v-if="comment.replyTotalCount > 0 && !comment.expandReply" @click="loadRepliesPage(comment, index)">
+ <text class="line">鈥斺��</text>灞曞紑{{comment.replyTotalCount}}鏉″洖澶� 鈫�
+ </view>
+ <view class="reply-op" v-if="comment.replyTotalCount > replyCommentQuery.pageNumber * replyCommentQuery.pageSize && comment.expandReply">
+ <view @click="loadNextPageReply(index)" class="reply-op-item"><text class="line">鈥斺��</text>灞曞紑鏇村<text class="iconfont textSideIcon"></text></view>
+ <view @click="retractReplyComment(index)" class="reply-op-item" style="margin-left: 50rpx;">鏀惰捣<text class="iconfont textSideIcon"></text></view>
+ </view>
+ <view class="reply-op" v-else-if="comment.replyTotalCount <= replyCommentQuery.pageNumber * replyCommentQuery.pageSize && comment.expandReply">
+ <view @click="retractReplyComment(index)" class="reply-op-item"><text class="line">鈥斺��</text>鏀惰捣<text class="iconfont textSideIcon"></text></view>
+ </view>
+ </view>
+ </scroll-view>
+ <view class="comment-input-area">
+ <input
+ ref="commentInput"
+ class="comment-input"
+ v-model="commentForm.commentContent"
+ :placeholder="commentForm.replyId ? `鍥炲 @${commentForm.replyUserNickname}` : '鍐欎笅浣犵殑璇勮...'"
+ placeholder-class="placeholder"
+ />
+ <button class="submit-btn" @click="submitComment" :disabled="!commentForm.commentContent.trim()">鍙戦��</button>
+ </view>
+ </view>
+ </uni-popup>
+ <uni-drawer ref="showLeft" mode="left" width="120" :cus-style="true" height="93vh"
+ @change="change($event,'showLeft')" class="navigationLeft">
+ <scroll-view class="typeNavigation" :scroll-y="true" :show-scrollbar="false">
+ <view class="typeNavigationItem" :class="{typeNavigationItemCheck:currentCategort ==item.id}"
+ @click="chooseCategory(item.id)" v-for="item in categoryList" :key="item.id">
+ {{item.typeName}}
+ </view>
+ </scroll-view>
+ </uni-drawer>
+ <view v-if="videoList.length===0" style="display: flex;align-items: center;justify-content: center;background-color: #fff;height: 100%">褰撳墠娌℃湁鍙互鏌ョ湅鐨勮棰�</view>
+
+ <custom-tabbar bgColor="#ffffff" selected="kitchen"></custom-tabbar>
+ </view>
</template>
<script>
- import {
- getkitchenTypeList,
- getkitchenVideoList,
- savePlayRecord,
- subscribe,
- getVideoComments,
- addVideoComment,
- thubmsUpComment,
- cancelThubmsUpComment
- } from "@/api/video.js";
- import {
- changeCollect
- } from "@/api/collect.js";
- export default {
- computed: {
- hasPlayTime() {
- return this.sliderFormatTime(this.progress > 0 ? this.duration * this.progress / 100 : 0);
- }
- },
- data() {
- return {
- currentCategort: '',
- categoryList: [],
- currentImgIndex: 0, // 鎾斁鍒扮鍑犲紶鍥�--绱㈠紩
- currentTime: 0,
- formartDuration: [],
- duration: 0,
- startX: 0,
- progress: 0, // 瑙嗛杩涘害
- startProgress: 0, // 寮�濮嬫粦鍔ㄦ椂鐨勮繘搴�
- barLeft: 0, // 杩涘害鏉″乏杈圭晫浣嶇疆
- barWidth: 0, // 杩涘害鏉″搴�
- isDragging: false, // 鏄惁姝e湪鎷栧姩
- processHidenTimer: null, // 杩涘害鏉¢殣钘忓畾鏃跺櫒
- showProcess: false, // 鏄惁鏄剧ず杩涘害鏉�
- videoNoMore: false, // 鏄惁杩樻湁鏇村瑙嗛
- commentNoMore: false, // 鏄惁杩樻湁鏇村璇勮
- commentQuery: {
- pageNumber: 1,
- pageSize: 5,
- videoId: '',
- masterCommentId: ''
- },
- replyCommentQuery: {
- pageNumber: 1,
- pageSize: 5,
- videoId: '',
- masterCommentId: ''
- },
- commentForm: { // 璇勮琛ㄥ崟鏁版嵁
- id: '',
- videoId: '',
- commentContent: '',
- replyId: '',
- replyUserId: '',
- replyUserNickname: '',
- replyUserAvatar: '',
- masterCommentId: null
- },
- comments: [], // 璇勮鍒楄〃
- commentsTotal: 0, // 璇勮鎬绘潯鏁�
- commentLoading: false, // 璇勮鍔犺浇鐘舵��
- startHidenTime: 0, // 璁板綍鍒囨崲鑷冲叾瀹冮〉闈㈢殑鏃堕棿锛岀敤浜庤绠楄棰戣鐪嬫椂闂村噺鍘荤殑閮ㄥ垎
- totalHidenTime: 0, // 鎬诲叡闅愯棌椤甸潰鐨勬椂闂�
- startPauseTime: 0, // 寮�濮嬫殏鍋滅殑鏃堕棿
- totalPauseTime: 0, // 鎬诲叡鏆傚仠鐨勬椂闂�
- playRecord: {
- videoId: null,
- viewDuration: 0, // 杩欎釜瑙嗛鎬诲叡瑙傜湅浜嗗涔�
- playAt: 0, // 杩欎釜瑙嗛鎾斁鍒板摢浜�
- startPlayTime: 0 // 杩欎釜瑙嗛浠庝粈涔堟椂鍊欏紑濮嬫挱鏀剧殑
- },
- currentVideoIsPlaying: true, // 褰撳墠瑙嗛鏄惁姝e湪鎾斁
- isFullScreen: false,
- windowHeight: 0,
- currentIndex: 0, // 褰撳墠鎾斁鐨勮棰戠储寮�
- videoList: [
+import {
+ getkitchenTypeList,
+ getkitchenVideoList,
+ savePlayRecord,
+ subscribe,
+ getVideoComments,
+ addVideoComment,
+ thubmsUpComment,
+ cancelThubmsUpComment
+} from "@/api/video.js";
+import {
+ changeCollect
+} from "@/api/collect.js";
+export default {
+ computed: {
+ hasPlayTime() {
+ return this.sliderFormatTime(this.progress > 0 ? this.duration * this.progress / 100 : 0);
+ }
+ },
+ data() {
+ return {
+ showLeft:false,
+ currentCategort: '',
+ categoryList: [],
+ currentImgIndex: 0, // 鎾斁鍒扮鍑犲紶鍥�--绱㈠紩
+ currentTime: 0,
+ formartDuration: [],
+ duration: 0,
+ startX: 0,
+ progress: 0, // 瑙嗛杩涘害
+ startProgress: 0, // 寮�濮嬫粦鍔ㄦ椂鐨勮繘搴�
+ barLeft: 0, // 杩涘害鏉″乏杈圭晫浣嶇疆
+ barWidth: 0, // 杩涘害鏉″搴�
+ isDragging: false, // 鏄惁姝e湪鎷栧姩
+ processHidenTimer: null, // 杩涘害鏉¢殣钘忓畾鏃跺櫒
+ showProcess: false, // 鏄惁鏄剧ず杩涘害鏉�
+ videoNoMore: false, // 鏄惁杩樻湁鏇村瑙嗛
+ commentNoMore: false, // 鏄惁杩樻湁鏇村璇勮
+ commentQuery: {
+ pageNumber: 1,
+ pageSize: 5,
+ videoId: '',
+ masterCommentId: ''
+ },
+ replyCommentQuery: {
+ pageNumber: 1,
+ pageSize: 5,
+ videoId: '',
+ masterCommentId: ''
+ },
+ commentForm: { // 璇勮琛ㄥ崟鏁版嵁
+ id: '',
+ videoId: '',
+ commentContent: '',
+ replyId: '',
+ replyUserId: '',
+ replyUserNickname: '',
+ replyUserAvatar: '',
+ masterCommentId: null
+ },
+ comments: [], // 璇勮鍒楄〃
+ commentsTotal: 0, // 璇勮鎬绘潯鏁�
+ commentLoading: false, // 璇勮鍔犺浇鐘舵��
+ startHidenTime: 0, // 璁板綍鍒囨崲鑷冲叾瀹冮〉闈㈢殑鏃堕棿锛岀敤浜庤绠楄棰戣鐪嬫椂闂村噺鍘荤殑閮ㄥ垎
+ totalHidenTime: 0, // 鎬诲叡闅愯棌椤甸潰鐨勬椂闂�
+ startPauseTime: 0, // 寮�濮嬫殏鍋滅殑鏃堕棿
+ totalPauseTime: 0, // 鎬诲叡鏆傚仠鐨勬椂闂�
+ playRecord: {
+ videoId: null,
+ viewDuration: 0, // 杩欎釜瑙嗛鎬诲叡瑙傜湅浜嗗涔�
+ playAt: 0, // 杩欎釜瑙嗛鎾斁鍒板摢浜�
+ startPlayTime: 0 // 杩欎釜瑙嗛浠庝粈涔堟椂鍊欏紑濮嬫挱鏀剧殑
+ },
+ currentVideoIsPlaying: true,
+ isFullScreen: false,
+ windowHeight: 0,
+ currentIndex: 0, // 褰撳墠鎾斁鐨勮棰戠储寮�
+ videoLoading: false, // 瑙嗛缂撳啿涓�// 褰撳墠瑙嗛鏄惁姝e湪鎾斁
+ videoList: [], // 瑙嗛鍒楄〃鏁版嵁
+ videoBufferOffset: 0.1 ,// 瑙嗛棰勫姞杞藉弬鏁�
+ videoLiveOffset: 2, // 淇濈暀褰撳墠瑙嗛鍓嶅悗鍚勫灏戜釜瑙嗛涓婁笅鏂�
+ touchXY: { // 鐩戝惉宸︽粦鍙虫粦
+ startX: 0,
+ endX: 0,
+ startY: 0,
+ endY: 0
+ },
- ], // 瑙嗛鍒楄〃鏁版嵁
- videoContexts: [], // 瑙嗛涓婁笅鏂囧璞¢泦鍚�
- loading: false, // 鏄惁姝e湪鍔犺浇
- videoQuery: {
- pageNumber: 1,
- pageSize: 6,
- videoFrom: 'recommend',
- videoType: 'cook'
- }
- }
- },
- onShow() {
- this.showDrawer('showLeft')
- this.loadVideos()
- // 濡傛灉瑙嗛鎸変笅鏆傚仠鍚庡垏鎹㈤〉闈㈠啀鍥炲埌椤甸潰鏃讹紝鍙畻鏆傚仠鏃堕棿锛堝洜涓烘殏鍋滄椂闂村拰绂诲紑椤甸潰鏃堕棿鏄噸澶嶇殑锛屽彧绠椾竴涓級
- if (this.startHidenTime !== 0 && this.currentVideoIsPlaying) {
- const duration = Date.now() - this.startHidenTime
- this.totalHidenTime += duration
- }
- },
- onHide() {
- this.startHidenTime = Date.now()
- },
- onLoad() {
- this.getKitchenTypeList();
- this.loadVideos();
- },
- onReady() {
- // 鍒濆鍖栬棰戜笂涓嬫枃
- this.initVideoContexts();
- },
- methods: {
- async chooseCategory(id) {
- if (this.currentCategort === id) return
- this.currentCategort = id
- this.videoQuery.pageNumber = 1,
- this.videoQuery.kitchenTypeId = id;
- await this.loadVideos()
- },
- getKitchenTypeList() {
- getkitchenTypeList().then(res => {
- this.categoryList = res.data.data
- })
- },
- showDrawer(e) {
- this.$refs[e].open()
- },
- // 鍏抽棴绐楀彛
- closeDrawer(e) {
- this.$refs[e].close()
- },
- // 鎶藉眽鐘舵�佸彂鐢熷彉鍖栬Е鍙�
- change(e, type) {
- this[type] = e
- },
- // 杞挱鍥惧彉鍖�
- imgChange(e) {
- this.currentImgIndex = e.detail.current;
- },
- // 鑾峰彇杩涘害鏉$殑浣嶇疆鍜屽昂瀵�
- getBarRect() {
- const query = uni.createSelectorQuery().in(this);
- query.select('#progressBar').boundingClientRect(rect => {
- if (rect) {
- this.barLeft = rect.left;
- this.barWidth = rect.width;
- }
- }).exec();
- },
- // 璺宠浆涓汉涓婚〉
- jumpToHomePage(authorId) {
- uni.navigateTo({
- url: "/pages/video/home-page?authorId=" + authorId
- })
- },
- // 鍙栨秷鐐硅禐
- async cancelThumbsUp(id, commentIndex, replyIndex) {
- const data = {
- refId: id,
- thumbsUpType: 'video_comment'
- }
- cancelThubmsUpComment(data).then(res => {
- if (replyIndex != null) {
- this.comments[commentIndex].replies[replyIndex].hasThumbsUp = false;
- this.comments[commentIndex].replies[replyIndex].thumbsUpNum -= 1;
- } else {
- this.comments[commentIndex].hasThumbsUp = false;
- this.comments[commentIndex].thumbsUpNum -= 1;
- }
- })
- },
- // 璇勮鐐硅禐
- async thubmsUp(id, commentIndex, replyIndex) {
- const data = {
- refId: id,
- thumbsUpType: 'video_comment'
- }
- thubmsUpComment(data).then(res => {
- if (replyIndex != null) {
- this.comments[commentIndex].replies[replyIndex].hasThumbsUp = true;
- this.comments[commentIndex].replies[replyIndex].thumbsUpNum += 1;
- } else {
- this.comments[commentIndex].hasThumbsUp = true;
- this.comments[commentIndex].thumbsUpNum += 1;
- }
- })
- },
- // 鍔犺浇涓嬩竴椤靛洖澶�
- loadNextPageReply(index) {
- this.replyCommentQuery.pageNumber++;
- getVideoComments(this.replyCommentQuery).then(res => {
- this.comments[index].replies = [
- ...this.comments[index].replies,
- ...res.data.data.filter(
- (newItem) => !this.comments[index].replies.some((oldItem) => oldItem.id === newItem
- .id)
- ),
- ];
- })
- },
- // 鏀惰捣鍥炲
- retractReplyComment(index) {
- this.comments[index].expandReply = false;
- this.comments[index].replies = [];
- },
- // 鍔犺浇鍥炲
- loadRepliesPage(comment, index) {
- this.replyCommentQuery.pageNumber = 1;
- this.replyCommentQuery.masterCommentId = comment.id
- getVideoComments(this.replyCommentQuery).then(res => {
- this.comments[index].replies = res.data.data;
- this.comments[index].expandReply = true;
- })
- },
- resetCommentForm() {
- const videoId = this.commentForm.videoId;
- this.commentForm = { // 璇勮琛ㄥ崟鏁版嵁
- id: '',
- videoId: videoId,
- commentContent: '',
- replyId: '',
- replyUserId: '',
- replyUserNickname: '',
- replyUserAvatar: '',
- masterCommentId: null
- }
- },
- // 鍙栨秷鍥炲
- cancelReply() {
- this.resetCommentForm()
- },
- // 鎵撳紑鍥炲妗�
- openReply(comment, reply = null) {
- if (reply) {
- comment = reply
- }
- this.commentForm.masterCommentId = comment.masterCommentId ? comment.masterCommentId : comment.id;
- this.commentForm.replyId = comment.id;
- this.commentForm.replyUserId = comment.userId;
- this.commentForm.replyUserNickname = comment.userNickname;
- this.commentForm.replyUserAvatar = comment.userAvatar;
- // 鑷姩鑱氱劍杈撳叆妗�
- this.$nextTick(() => {
- const input = this.$refs.commentInput;
- if (input) input.focus();
- });
- },
- // 杩涘害鏉℃椂闂存牸寮忓寲 (00:00)
- sliderFormatTime(seconds) {
- const mins = Math.floor(seconds / 60);
- const secs = Math.floor(seconds % 60);
- return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
- },
- // 鏍煎紡鍖栨椂闂�
- formatTime(time) {
- const date = new Date(time);
- const now = new Date();
- const diff = Math.floor((now - date) / 1000); // 绉�
+ videoContexts: [], // 瑙嗛涓婁笅鏂囧璞¢泦鍚�
+ loading: false, // 鏄惁姝e湪鍔犺浇
+ videoQuery: {
+ pageNumber: 1,
+ pageSize: 6,
+ videoFrom: 'recommend',
+ videoType: 'cook'
+ }
+ }
+ },
+ onShow() {
+ this.showDrawer('showLeft')
+ this.loadVideos()
+ // 濡傛灉瑙嗛鎸変笅鏆傚仠鍚庡垏鎹㈤〉闈㈠啀鍥炲埌椤甸潰鏃讹紝鍙畻鏆傚仠鏃堕棿锛堝洜涓烘殏鍋滄椂闂村拰绂诲紑椤甸潰鏃堕棿鏄噸澶嶇殑锛屽彧绠椾竴涓級
+ if (this.startHidenTime !== 0 && this.currentVideoIsPlaying) {
+ const duration = Date.now() - this.startHidenTime
+ this.totalHidenTime += duration
+ }
+ },
+ onHide() {
+ this.startHidenTime = Date.now()
+ },
+ onLoad() {
+ this.getKitchenTypeList();
+ this.loadVideos();
+ },
+ onReady() {
+ // 鍒濆鍖栬棰戜笂涓嬫枃
+ this.initVideoContexts();
+ },
+ methods: {
+ async chooseCategory(id) {
+ if (this.currentCategort === id) return
+ this.currentCategort = id
+ this.videoQuery.pageNumber = 1
+ this.videoQuery.kitchenTypeId = id;
+ this.videoLoading = false;
+ this.currentIndex = 0;
+
+ await this.loadVideos()
+ },
+ getKitchenTypeList() {
+ getkitchenTypeList().then(res => {
+ this.categoryList = res.data.data
+ })
+ },
+ showDrawer(e) {
+ this.$refs[e].open()
+ },
+ // 鍏抽棴绐楀彛
+ closeDrawer(e) {
+ this.$refs[e].close()
+ },
+ // 鎶藉眽鐘舵�佸彂鐢熷彉鍖栬Е鍙�
+ change(e, type) {
+ this[type] = e
+ },
+ // 杞挱鍥惧彉鍖�
+ imgChange(e) {
+ this.currentImgIndex = e.detail.current;
+ },
+ // 鑾峰彇杩涘害鏉$殑浣嶇疆鍜屽昂瀵�
+ getBarRect() {
+ const query = uni.createSelectorQuery().in(this);
+ query.select('#progressBar').boundingClientRect(rect => {
+ if (rect) {
+ this.barLeft = rect.left;
+ this.barWidth = rect.width;
+ }
+ }).exec();
+ },
+ // 璺宠浆涓汉涓婚〉
+ jumpToHomePage(authorId) {
+ uni.navigateTo({
+ url: "/pages/video/home-page?authorId=" + authorId
+ })
+ },
+ // 鍙栨秷鐐硅禐
+ async cancelThumbsUp(id, commentIndex, replyIndex) {
+ const data = {
+ refId: id,
+ thumbsUpType: 'video_comment'
+ }
+ cancelThubmsUpComment(data).then(res => {
+ if (replyIndex != null) {
+ this.comments[commentIndex].replies[replyIndex].hasThumbsUp = false;
+ this.comments[commentIndex].replies[replyIndex].thumbsUpNum -= 1;
+ } else {
+ this.comments[commentIndex].hasThumbsUp = false;
+ this.comments[commentIndex].thumbsUpNum -= 1;
+ }
+ })
+ },
+ // 璇勮鐐硅禐
+ async thubmsUp(id, commentIndex, replyIndex) {
+ const data = {
+ refId: id,
+ thumbsUpType: 'video_comment'
+ }
+ thubmsUpComment(data).then(res => {
+ if (replyIndex != null) {
+ this.comments[commentIndex].replies[replyIndex].hasThumbsUp = true;
+ this.comments[commentIndex].replies[replyIndex].thumbsUpNum += 1;
+ } else {
+ this.comments[commentIndex].hasThumbsUp = true;
+ this.comments[commentIndex].thumbsUpNum += 1;
+ }
+ })
+ },
+ // 鍔犺浇涓嬩竴椤靛洖澶�
+ loadNextPageReply(index) {
+ this.replyCommentQuery.pageNumber++;
+ getVideoComments(this.replyCommentQuery).then(res => {
+ this.comments[index].replies = [
+ ...this.comments[index].replies,
+ ...res.data.data.filter(
+ (newItem) => !this.comments[index].replies.some((oldItem) => oldItem.id === newItem
+ .id)
+ ),
+ ];
+ })
+ },
+ // 鏀惰捣鍥炲
+ retractReplyComment(index) {
+ this.comments[index].expandReply = false;
+ this.comments[index].replies = [];
+ },
+ // 鍔犺浇鍥炲
+ loadRepliesPage(comment, index) {
+ this.replyCommentQuery.pageNumber = 1;
+ this.replyCommentQuery.masterCommentId = comment.id
+ getVideoComments(this.replyCommentQuery).then(res => {
+ this.comments[index].replies = res.data.data;
+ this.comments[index].expandReply = true;
+ })
+ },
+ resetCommentForm() {
+ const videoId = this.commentForm.videoId;
+ this.commentForm = { // 璇勮琛ㄥ崟鏁版嵁
+ id: '',
+ videoId: videoId,
+ commentContent: '',
+ replyId: '',
+ replyUserId: '',
+ replyUserNickname: '',
+ replyUserAvatar: '',
+ masterCommentId: null
+ }
+ },
+ // 鍙栨秷鍥炲
+ cancelReply() {
+ this.resetCommentForm()
+ },
+ // 鎵撳紑鍥炲妗�
+ openReply(comment, reply = null) {
+ if (reply) {
+ comment = reply
+ }
+ this.commentForm.masterCommentId = comment.masterCommentId ? comment.masterCommentId : comment.id;
+ this.commentForm.replyId = comment.id;
+ this.commentForm.replyUserId = comment.userId;
+ this.commentForm.replyUserNickname = comment.userNickname;
+ this.commentForm.replyUserAvatar = comment.userAvatar;
+ // 鑷姩鑱氱劍杈撳叆妗�
+ this.$nextTick(() => {
+ const input = this.$refs.commentInput;
+ if (input) input.focus();
+ });
+ },
+ // 杩涘害鏉℃椂闂存牸寮忓寲 (00:00)
+ sliderFormatTime(seconds) {
+ const mins = Math.floor(seconds / 60);
+ const secs = Math.floor(seconds % 60);
+ return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
+ },
+ // 鏍煎紡鍖栨椂闂�
+ formatTime(time) {
+ const date = new Date(time);
+ const now = new Date();
+ const diff = Math.floor((now - date) / 1000); // 绉�
- if (diff < 60) return '鍒氬垰';
- if (diff < 3600) return `${Math.floor(diff / 60)}鍒嗛挓鍓峘;
- if (diff < 86400) return `${Math.floor(diff / 3600)}灏忔椂鍓峘;
+ if (diff < 60) return '鍒氬垰';
+ if (diff < 3600) return `${Math.floor(diff / 60)}鍒嗛挓鍓峘;
+ if (diff < 86400) return `${Math.floor(diff / 3600)}灏忔椂鍓峘;
- return `${date.getMonth() + 1}鏈�${date.getDate()}鏃;
- },
- // 鎻愪氦璇勮
- async submitComment() {
- if (!this.commentForm.commentContent.trim()) {
- uni.showToast({
- title: '璇勮鍐呭涓嶈兘涓虹┖',
- icon: 'none'
- });
- return;
- }
- // 鍙戣〃璇勮
- addVideoComment(this.commentForm).then(res => {
- if (res.data.code === 200) {
- this.resetCommentForm()
+ return `${date.getMonth() + 1}鏈�${date.getDate()}鏃;
+ },
+ // 鎻愪氦璇勮
+ async submitComment() {
+ if (!this.commentForm.commentContent.trim()) {
+ uni.showToast({
+ title: '璇勮鍐呭涓嶈兘涓虹┖',
+ icon: 'none'
+ });
+ return;
+ }
+ // 鍙戣〃璇勮
+ addVideoComment(this.commentForm).then(res => {
+ if (res.data.code === 200) {
+ this.resetCommentForm()
- // 濡傛灉鏄瘎璁哄埆浜虹殑鍥炲锛岄偅涔堝氨灏嗚繖涓彂甯冨埌replies閲岄潰
- if (res.data.data.replyId) {
- for (const [index, item] of this.comments.entries()) {
- if (item.id === res.data.data.replyId) {
- item.replies.unshift(res.data.data);
- // this.loadRepliesPage(item, index)
- break; // 璺冲嚭寰幆
- }
- }
- } else {
- this.comments.unshift(res.data.data);
- }
- console.log("鏂板鍚�", this.comments);
- uni.showToast({
- title: '璇勮鎴愬姛'
- });
- // 褰撳墠瑙嗛璇勮鏁板姞涓�
- this.commentsTotal += 1;
- this.videoList[this.currentIndex].commentNum += 1;
- } else {
- uni.showToast({
- title: res.data.msg,
- icon: 'none'
- });
- }
- }).catch(() => {
- uni.showToast({
- title: '璇勮澶辫触',
- icon: 'none'
- });
- })
- },
- // 鍏抽棴璇勮寮圭獥
- closeCommentPopup() {
- this.$refs.commentPopup.close()
- this.showCommentPopup = false;
- this.comments = [];
- this.resetCommentForm()
- this.commentQuery.pageNumber = 1;
- this.commentNoMore = false;
- },
- // 涓嬫粦璇勮鍖哄姞杞借瘎璁�
- async getCommentPage() {
- if (this.commentNoMore) {
- return;
- }
- getVideoComments(this.commentQuery).then(res => {
- if (this.commentQuery.pageNumber === 1) {
- this.comments = res.data.data
- } else {
- this.comments = [
- ...this.comments,
- ...res.data.data.filter(
- (newItem) => !this.comments.some((oldItem) => oldItem.id === newItem.id)
- ),
- ];
- }
- if (res.data.data.length < this.commentQuery.pageSize) {
- this.commentNoMore = true;
- return;
- }
- this.commentQuery.pageNumber++;
- })
- },
- // 鏄剧ず璇勮寮圭獥
- async showComments(item) {
- this.commentForm.videoId = item.id;
- this.$refs.commentPopup.open();
- this.commentLoading = true;
- this.commentQuery.videoId = item.id
- this.replyCommentQuery.videoId = item.id
- // 棣栨鍔犺浇璇勮鍒嗛〉澶у皬澧炲姞涓�鍊嶏紝浠ヤ骇鐢熸粴鍔ㄦ潯锛屽悗缁彲瑙﹀彂
- this.commentQuery.pageSize *= 2;
- getVideoComments(this.commentQuery).then(res => {
- this.commentsTotal = res.data.total;
- this.comments = res.data.data;
- this.commentQuery.pageNumber += 2;
- this.commentQuery.pageSize /= 2;
- }).catch(() => {
- uni.showToast({
- title: '鑾峰彇璇勮澶辫触',
- icon: 'none'
- });
- }).finally(() => {
- this.commentLoading = false;
- })
- },
- // 鍏虫敞浣滆��
- subscribeAuth(index, authorId) {
- this.videoList.forEach(video => {
- if (video.authorId === authorId) {
- video.subscribeThisAuthor = true
- }
- })
- subscribe(authorId).then(res => {
- if (res.data.code === 200) {
- uni.showToast({
- title: '鍏虫敞鎴愬姛~',
- icon: 'none'
- });
- } else {
- this.videoList.forEach(video => {
- if (video.authorId === authorId) {
- video.subscribeThisAuthor = false
- }
- })
- }
- })
- },
- // 鍒濆鍖栬棰戜笂涓嬫枃
- initVideoContexts() {
- this.videoContexts = this.videoList.map((_, index) => {
- let videoContent = uni.createVideoContext(`video${index}`, this);
- return videoContent;
- });
- },
+ // 濡傛灉鏄瘎璁哄埆浜虹殑鍥炲锛岄偅涔堝氨灏嗚繖涓彂甯冨埌replies閲岄潰
+ if (res.data.data.replyId) {
+ for (const [index, item] of this.comments.entries()) {
+ if (item.id === res.data.data.replyId) {
+ item.replies.unshift(res.data.data);
+ // this.loadRepliesPage(item, index)
+ break; // 璺冲嚭寰幆
+ }
+ }
+ } else {
+ this.comments.unshift(res.data.data);
+ }
+ console.log("鏂板鍚�", this.comments);
+ uni.showToast({
+ title: '璇勮鎴愬姛'
+ });
+ // 褰撳墠瑙嗛璇勮鏁板姞涓�
+ this.commentsTotal += 1;
+ this.videoList[this.currentIndex].commentNum += 1;
+ } else {
+ uni.showToast({
+ title: res.data.msg,
+ icon: 'none'
+ });
+ }
+ }).catch(() => {
+ uni.showToast({
+ title: '璇勮澶辫触',
+ icon: 'none'
+ });
+ })
+ },
+ // 鍏抽棴璇勮寮圭獥
+ closeCommentPopup() {
+ this.$refs.commentPopup.close()
+ this.showCommentPopup = false;
+ this.comments = [];
+ this.resetCommentForm()
+ this.commentQuery.pageNumber = 1;
+ this.commentNoMore = false;
+ },
+ // 涓嬫粦璇勮鍖哄姞杞借瘎璁�
+ async getCommentPage() {
+ if (this.commentNoMore) {
+ return;
+ }
+ getVideoComments(this.commentQuery).then(res => {
+ if (this.commentQuery.pageNumber === 1) {
+ this.comments = res.data.data
+ } else {
+ this.comments = [
+ ...this.comments,
+ ...res.data.data.filter(
+ (newItem) => !this.comments.some((oldItem) => oldItem.id === newItem.id)
+ ),
+ ];
+ }
+ if (res.data.data.length < this.commentQuery.pageSize) {
+ this.commentNoMore = true;
+ return;
+ }
+ this.commentQuery.pageNumber++;
+ })
+ },
+ // 鏄剧ず璇勮寮圭獥
+ async showComments(item) {
+ this.commentForm.videoId = item.id;
+ this.$refs.commentPopup.open();
+ this.commentLoading = true;
+ this.commentQuery.videoId = item.id
+ this.replyCommentQuery.videoId = item.id
+ // 棣栨鍔犺浇璇勮鍒嗛〉澶у皬澧炲姞涓�鍊嶏紝浠ヤ骇鐢熸粴鍔ㄦ潯锛屽悗缁彲瑙﹀彂
+ this.commentQuery.pageSize *= 2;
+ getVideoComments(this.commentQuery).then(res => {
+ this.commentsTotal = res.data.total;
+ this.comments = res.data.data;
+ this.commentQuery.pageNumber += 2;
+ this.commentQuery.pageSize /= 2;
+ }).catch(() => {
+ uni.showToast({
+ title: '鑾峰彇璇勮澶辫触',
+ icon: 'none'
+ });
+ }).finally(() => {
+ this.commentLoading = false;
+ })
+ },
+ // 鍏虫敞浣滆��
+ subscribeAuth(index, authorId) {
+ this.videoList.forEach(video => {
+ if (video.authorId === authorId) {
+ video.subscribeThisAuthor = true
+ }
+ })
+ subscribe(authorId).then(res => {
+ if (res.data.code === 200) {
+ uni.showToast({
+ title: '鍏虫敞鎴愬姛~',
+ icon: 'none'
+ });
+ } else {
+ this.videoList.forEach(video => {
+ if (video.authorId === authorId) {
+ video.subscribeThisAuthor = false
+ }
+ })
+ }
+ })
+ },
+ // 鍒濆鍖栬棰戜笂涓嬫枃
+ initVideoContexts() {
+ this.videoContexts = this.videoList.map((_, index) => {
+ let videoContent = uni.createVideoContext(`video${index}`, this);
+ return videoContent;
+ });
+ },
- // 鍔犺浇瑙嗛鏁版嵁
- async loadVideos() {
- console.log(this.loading, this.videoNoMore,this.videoQuery)
- if (this.videoQuery.pageNumber == 1) {
+ // 鍔犺浇瑙嗛鏁版嵁
+ async loadVideos() {
+ console.log(this.loading, this.videoNoMore,this.videoQuery)
+ if (this.videoQuery.pageNumber == 1) {
- } else if (this.loading || this.videoNoMore) return;
- this.loading = true;
+ } else if (this.loading || this.videoNoMore) return;
+ this.loading = true;
- getkitchenVideoList(this.videoQuery).then(res => {
- console.log(res, "瑙嗛鏁版嵁");
- if (this.videoQuery.pageNumber === 1) {
- this.videoList = res.data.data;
- } else {
- this.videoList = [
- ...this.videoList,
- ...res.data.data.filter(
- (newItem) => !this.videoList.some((oldItem) => oldItem.id === newItem.id)
- ),
- ];
- }
- this.$nextTick(() => {
- this.initVideoContexts();
- });
- this.loading = false;
- if (res.data.data.length < this.videoQuery.pageSize) {
- this.videoNoMore = true;
- return;
- }
- this.videoQuery.pageNumber++;
+ getkitchenVideoList(this.videoQuery).then(res => {
+ console.log(res, "瑙嗛鏁版嵁");
+ if (this.videoQuery.pageNumber === 1) {
+ this.videoList = res.data.data;
+ } else {
+ this.videoList = [
+ ...this.videoList,
+ ...res.data.data.filter(
+ (newItem) => !this.videoList.some((oldItem) => oldItem.id === newItem.id)
+ ),
+ ];
+ }
+ this.$nextTick(() => {
+ this.initVideoContexts();
+ });
+ this.loading = false;
+ if (res.data.data.length < this.videoQuery.pageSize) {
+ this.videoNoMore = true;
+ return;
+ }
+ this.videoQuery.pageNumber++;
- })
- },
+ })
+ },
- // 婊戝姩鍒囨崲瑙嗛
- onSwiperChange(e) {
- // 濡傛灉瑙嗛澶勪簬鏆傚仠鐘舵�佸線涓嬪埛瑙嗛锛岄偅涔堥渶瑕佸啀璁$畻涓�娆℃殏鍋滄椂闂�
- if (!this.currentVideoIsPlaying) {
- if (this.startPauseTime !== 0) {
- const duration = Date.now() - this.startPauseTime
- this.totalPauseTime += duration
- }
- }
- // 淇濆瓨涓婁竴涓棰戠殑鎾斁璁板綍
- this.savePlayRecord()
- const oldIndex = this.currentIndex;
- this.currentIndex = e.detail.current;
+ // 婊戝姩鍒囨崲瑙嗛
+ onSwiperChange(e) {
+ // 濡傛灉瑙嗛澶勪簬鏆傚仠鐘舵�佸線涓嬪埛瑙嗛锛岄偅涔堥渶瑕佸啀璁$畻涓�娆℃殏鍋滄椂闂�
+ if (!this.currentVideoIsPlaying) {
+ if (this.startPauseTime !== 0) {
+ const duration = Date.now() - this.startPauseTime
+ this.totalPauseTime += duration
+ }
+ }
+ // 淇濆瓨涓婁竴涓棰戠殑鎾斁璁板綍
+ this.savePlayRecord()
+ const oldIndex = this.currentIndex;
+ this.currentIndex = e.detail.current;
- // 鏆傚仠涓婁竴涓棰�
- if (this.videoContexts[oldIndex]) {
- this.videoContexts[oldIndex].pause();
- }
+ // 鏆傚仠涓婁竴涓棰�
+ if (this.videoContexts[oldIndex]) {
+ this.videoContexts[oldIndex].pause();
+ }
- this.startPauseTime = 0;
- // 鎾斁褰撳墠瑙嗛
- if (this.videoContexts[this.currentIndex]) {
- this.videoContexts[this.currentIndex].play();
- }
- },
+ this.startPauseTime = 0;
+ // 鎾斁褰撳墠瑙嗛
+ if (this.videoContexts[this.currentIndex]) {
+ this.videoContexts[this.currentIndex].play();
+ }
+ },
- // 鏀惰棌/鍙栨秷鏀惰棌
- toggleCollect(item, index) {
- let data = {
- refId: item.id,
- collectType: 'video'
- }
- const beforeCollected = item.collected
- const beforeCollectNum = item.collectNum
- if (item.collected) {
- this.videoList[index].collected = false
- this.videoList[index].collectNum -= 1
- } else {
- this.videoList[index].collected = true
- this.videoList[index].collectNum += 1
- }
- changeCollect(data).then(res => {
- if (res.data.code !== 200) {
- this.videoList[index].collected = beforeCollected
- this.videoList[index].collectNum = beforeCollectNum
- }
- })
- },
- // 鍗曞嚮灞忓箷锛氭殏鍋滄垨缁х画鎾斁
- togglePlay(index) {
- console.log("鍗曞嚮瑙嗛", index, this.videoContexts);
- if (this.currentVideoIsPlaying) {
- this.videoContexts[index].pause();
- } else {
- this.videoContexts[index].play();
- }
- },
- // 瑙嗛鎾斁浜嬩欢
- onPlay(id, index) {
- this.getBarRect()
- this.progress = 0
- console.log(id, index, "瑙﹀彂鎾斁");
- if (index === this.currentIndex) {
- this.currentVideoIsPlaying = true;
- } else {
- this.currentVideoIsPlaying = false;
- return
- }
- this.playRecord.videoId = id;
- // 娌″垵濮嬪寲鎵嶈祴鍊硷紝鍥犱负涓�涓棰戦噸澶嶆挱鏀緊nPlay浼氶噸澶嶈Е鍙�
- if (this.playRecord.startPlayTime === 0) {
- this.playRecord.startPlayTime = Date.now();
- }
- if (this.startPauseTime !== 0) {
- const duration = Date.now() - this.startPauseTime
- this.totalPauseTime += duration
- }
- },
+ // 鏀惰棌/鍙栨秷鏀惰棌
+ toggleCollect(item, index) {
+ let data = {
+ refId: item.id,
+ collectType: 'video'
+ }
+ const beforeCollected = item.collected
+ const beforeCollectNum = item.collectNum
+ if (item.collected) {
+ this.videoList[index].collected = false
+ this.videoList[index].collectNum -= 1
+ } else {
+ this.videoList[index].collected = true
+ this.videoList[index].collectNum += 1
+ }
+ changeCollect(data).then(res => {
+ if (res.data.code !== 200) {
+ this.videoList[index].collected = beforeCollected
+ this.videoList[index].collectNum = beforeCollectNum
+ }
+ })
+ },
+ // 鍗曞嚮灞忓箷锛氭殏鍋滄垨缁х画鎾斁
+ togglePlay(index) {
+ console.log("鍗曞嚮瑙嗛", index);
+ const videoContext = uni.createVideoContext(`video${index}`, this);
+ if(this.currentVideoIsPlaying) {
+ videoContext.pause();
+ } else {
+ videoContext.play();
+ }
+ },
+ // 瑙嗛鎾斁浜嬩欢
+ onPlay(id, index) {
+ if(index === this.currentIndex) {
+ this.currentVideoIsPlaying = true;
+ if(! this.duration) {
+ // 璁剧疆褰撳墠鎾斁瑙嗛鐨勬�绘椂闀�
+ this.duration = this.videoList[this.currentIndex].videoDuration;
+ this.formartDuration = this.sliderFormatTime(this.duration);
+ }
+ } else {
+ return
+ }
+ this.getBarRect()
+ this.progress = 0
+ console.log(id, index, "瑙﹀彂鎾斁");
+ this.playRecord.videoId = id;
+ // 娌″垵濮嬪寲鎵嶈祴鍊硷紝鍥犱负涓�涓棰戦噸澶嶆挱鏀緊nPlay浼氶噸澶嶈Е鍙�
+ if(this.playRecord.startPlayTime === 0) {
+ this.playRecord.startPlayTime = Date.now();
+ }
+ if(this.startPauseTime !== 0) {
+ const duration = Date.now() - this.startPauseTime
+ this.totalPauseTime += duration
+ }
+ this.videoLoading = false
+ },
- // 瑙嗛鏆傚仠浜嬩欢
- onPause(index) {
- console.log(index, "瑙﹀彂鏆傚仠");
- if (index === this.currentIndex) {
- this.currentVideoIsPlaying = false;
- } else {
- this.currentVideoIsPlaying = true;
- return
- }
- this.startPauseTime = Date.now()
- },
- // 瑙嗛缁撴潫浜嬩欢
- onEnded(index) {
- // this.currentVideoIsPlaying = false;
- },
+ // 瑙嗛鏆傚仠浜嬩欢
+ onPause(index) {
+ console.log(index, "瑙﹀彂鏆傚仠");
+ if (index === this.currentIndex) {
+ this.currentVideoIsPlaying = false;
+ } else {
+ this.currentVideoIsPlaying = true;
+ return
+ }
+ this.startPauseTime = Date.now()
+ },
+ // 瑙嗛缁撴潫浜嬩欢
+ onEnded(index) {
+ // this.currentVideoIsPlaying = false;
+ },
- // 璁板綍鎾斁鏃堕暱
- onTimeUpdate(e) {
- this.playRecord.playAt = e.detail.currentTime;
+ // 璁板綍鎾斁鏃堕暱
+ onTimeUpdate(e) {
+ this.videoLoading = false
+ this.playRecord.playAt = e.detail.currentTime;
- this.currentTime = e.detail.currentTime;
- this.progress = (e.detail.currentTime / this.duration) * 100
- },
- // 瑙︽懜寮�濮�
- handleTouchStart(e) {
- this.isDragging = true;
- this.showProcess = true;
- this.startProgress = this.progress; // 璁板綍寮�濮嬫椂鐨勮繘搴�
- this.startX = e.touches[0].pageX;
- console.log("璁板綍寮�濮嬫椂鐨勮繘搴�", this.startProgress);
- this.videoContexts[this.currentIndex].pause()
- // this.updateProgress(e);
- },
+ this.currentTime = e.detail.currentTime;
+ this.progress = (e.detail.currentTime / this.duration) * 100
+ },
+ // 瑙︽懜寮�濮�
+ handleTouchStart(e) {
+ this.isDragging = true;
+ this.showProcess = true;
+ this.startProgress = this.progress; // 璁板綍寮�濮嬫椂鐨勮繘搴�
+ this.startX = e.touches[0].pageX;
+ console.log("璁板綍寮�濮嬫椂鐨勮繘搴�", this.startProgress);
+ this.videoContexts[this.currentIndex].pause()
+ // this.updateProgress(e);
+ },
+ // 寮�濮嬭Е鎽�
+ handleSwiperStart(e) {
+ console.log("寮�濮嬭Е鎽�", e);
+ this.touchXY.startX = e.touches[0].pageX
+ this.touchXY.startY = e.touches[0].pageY
+ },
+ // 瑙︽懜涓�
+ handleSwiperMove(e) {
+ this.touchXY.endX = e.touches[0].pageX
+ this.touchXY.endY = e.touches[0].pageY
+ },
+ // 缁撴潫瑙︽懜
+ handleSwiperEnd(item) {
+ // 闃叉婊戝姩婊氬姩鏉′篃瑙﹀彂璺宠浆
+ if (this.showProcess) {
+ return
+ }
+ const diffX = this.touchXY.endX - this.touchXY.startX
+ const diffY = this.touchXY.endY - this.touchXY.startY
- // 瑙︽懜绉诲姩
- handleTouchMove(e) {
- if (!this.isDragging || !this.barWidth) return;
- clearTimeout(this.processHidenTimer)
- this.videoContexts[this.currentIndex].pause()
- this.updateProgress(e);
- },
+ // 鍒ゆ柇鏄惁鏄í鍚戞粦鍔紙X杞村彉鍖栧ぇ浜嶻杞村彉鍖栵級
+ if (Math.abs(diffX) > Math.abs(diffY)) {
+ if (diffX > 0) {
+ console.log('鍙虫粦')
+ if (item.goodsList && item.goodsList.length > 0) {
+ this.jumpToPay(item.id)
+ }
+ } else {
+ console.log('宸︽粦')
+ }
+ }
+ // 閲嶇疆鍧愭爣
+ this.touchXY = {
+ startX: 0,
+ endX: 0,
+ startY: 0,
+ endY: 0
+ }
+ },
+ // 瑙︽懜绉诲姩
+ handleTouchMove(e) {
+ if (!this.isDragging || !this.barWidth) return;
+ clearTimeout(this.processHidenTimer)
+ this.videoContexts[this.currentIndex].pause()
+ this.updateProgress(e);
+ },
- // 瑙︽懜缁撴潫
- handleTouchEnd() {
- this.isDragging = false;
- console.log("婊戝姩缁撴潫", this.duration * this.progress);
- this.videoContexts[this.currentIndex].seek(this.duration * this.progress / 100)
- this.videoContexts[this.currentIndex].play()
- this.processHidenTimer = setTimeout(() => {
- this.showProcess = false;
- }, 1000);
- },
+ // 瑙︽懜缁撴潫
+ handleTouchEnd() {
+ this.isDragging = false;
+ console.log("婊戝姩缁撴潫", this.duration * this.progress);
+ this.videoContexts[this.currentIndex].seek(this.duration * this.progress / 100)
+ this.videoContexts[this.currentIndex].play()
+ this.processHidenTimer = setTimeout(() => {
+ this.showProcess = false;
+ }, 1000);
+ },
- // 鏇存柊杩涘害
- updateProgress(e) {
- // 鑾峰彇褰撳墠瑙︽懜鐐筙鍧愭爣
- const currentX = e.touches[0].pageX;
+ // 鏇存柊杩涘害
+ updateProgress(e) {
+ // 鑾峰彇褰撳墠瑙︽懜鐐筙鍧愭爣
+ const currentX = e.touches[0].pageX;
- // 璁$畻婊戝姩璺濈(鍍忕礌)
- const deltaX = currentX - this.startX;
+ // 璁$畻婊戝姩璺濈(鍍忕礌)
+ const deltaX = currentX - this.startX;
- // 灏嗗儚绱犺窛绂昏浆鎹负杩涘害澧為噺
- const deltaProgress = (deltaX / this.barWidth) * 100;
- console.log("杩涘害澧為噺", deltaProgress);
- // 璁$畻鏂拌繘搴� = 寮�濮嬫椂鐨勮繘搴� + 婊戝姩澧為噺
- let newProgress = this.startProgress + deltaProgress;
+ // 灏嗗儚绱犺窛绂昏浆鎹负杩涘害澧為噺
+ const deltaProgress = (deltaX / this.barWidth) * 100;
+ console.log("杩涘害澧為噺", deltaProgress);
+ // 璁$畻鏂拌繘搴� = 寮�濮嬫椂鐨勮繘搴� + 婊戝姩澧為噺
+ let newProgress = this.startProgress + deltaProgress;
- // 闄愬埗鑼冨洿鍦�0-100涔嬮棿
- newProgress = Math.max(0, Math.min(100, newProgress));
+ // 闄愬埗鑼冨洿鍦�0-100涔嬮棿
+ newProgress = Math.max(0, Math.min(100, newProgress));
- this.progress = newProgress;
- },
- // 鑾峰彇瑙嗛鎬绘椂闀�
- onLoadedMetadata(e) {
- this.duration = e.detail.duration;
- this.formartDuration.push(this.sliderFormatTime(this.duration));
- console.log("瑙嗛鎬绘椂闀�", this.duration);
- },
- // 淇濆瓨鎾斁璁板綍
- async savePlayRecord() {
- console.log(Date.now(), this.playRecord.startPlayTime, this.totalHidenTime);
+ this.progress = newProgress;
+ },
+ // 瑙嗛缂撳啿
+ videoWaiting(index) {
+ if (index === this.currentIndex) {
+ console.log("瑙嗛缂撳啿涓�傘�傘��");
+ this.videoLoading = true;
+ }
+ },
+ // 鑾峰彇瑙嗛鎬绘椂闀�
+ onLoadedMetadata(e) {
+ this.duration = e.detail.duration;
+ this.formartDuration.push(this.sliderFormatTime(this.duration));
+ console.log("瑙嗛鎬绘椂闀�", this.duration);
+ },
+ // 淇濆瓨鎾斁璁板綍
+ async savePlayRecord() {
+ console.log(Date.now(), this.playRecord.startPlayTime, this.totalHidenTime);
- const data = {
- videoId: this.playRecord.videoId,
- viewDuration: Date.now() - this.playRecord.startPlayTime - this.totalHidenTime - this
- .totalPauseTime,
- playAt: this.playRecord.playAt
- }
- this.playRecord = {
- videoId: null,
- viewDuration: 0, // 杩欎釜瑙嗛鎬诲叡瑙傜湅浜嗗涔�
- playAt: 0, // 杩欎釜瑙嗛鎾斁鍒板摢浜�
- startPlayTime: 0 // 杩欎釜瑙嗛浠庝粈涔堟椂鍊欏紑濮嬫挱鏀剧殑
- }
- this.totalHidenTime = 0
- this.totalPauseTime = 0
- savePlayRecord(data)
- }
- }
- }
+ const data = {
+ videoId: this.playRecord.videoId,
+ viewDuration: Date.now() - this.playRecord.startPlayTime - this.totalHidenTime - this
+ .totalPauseTime,
+ playAt: this.playRecord.playAt
+ }
+ this.playRecord = {
+ videoId: null,
+ viewDuration: 0, // 杩欎釜瑙嗛鎬诲叡瑙傜湅浜嗗涔�
+ playAt: 0, // 杩欎釜瑙嗛鎾斁鍒板摢浜�
+ startPlayTime: 0 // 杩欎釜瑙嗛浠庝粈涔堟椂鍊欏紑濮嬫挱鏀剧殑
+ }
+ this.totalHidenTime = 0
+ this.totalPauseTime = 0
+ savePlayRecord(data)
+ }
+ }
+}
</script>
<style scoped>
- ::v-deep .custom-tabbar {
- border-top: none !important;
- }
+::v-deep .custom-tabbar {
+ border-top: none !important;
+}
- .video-container {
- position: relative;
- width: 100%;
- height: 100vh;
- background-color: #000;
- }
+.video-container {
+ position: relative;
+ width: 100%;
+ height: 100vh;
+ background-color: #000;
+}
- .showLeft {
- display: flex;
- top: 50rpx;
- left: 0;
- align-items: center;
- justify-content: flex-start;
- background-color: #b6b6b6;
- opacity: 0.8;
- position: fixed;
- z-index: 999;
- height: 70rpx;
- width: 50rpx;
- border-radius: 0 50% 50% 0;
- }
+.showLeft {
+ display: flex;
+ top: 50rpx;
+ left: 0;
+ align-items: center;
+ justify-content: flex-start;
+ background-color: #b6b6b6;
+ opacity: 0.8;
+ position: fixed;
+ z-index: 999;
+ height: 70rpx;
+ width: 50rpx;
+ border-radius: 0 50% 50% 0;
+}
- .video-swiper {
- width: 100%;
- height: calc(100% - 50px);
- }
+.video-swiper {
+ width: 100%;
+ height: calc(100% - 50px);
+}
- .video-item {
- width: 100%;
- height: 100%;
- object-fit: cover;
- }
+.video-item {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
- .play-icon {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- width: 45px;
- height: 45px;
- z-index: 10;
- opacity: 0.6;
- }
+.play-icon {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 45px;
+ height: 45px;
+ z-index: 10;
+ opacity: 0.6;
+}
- .video-info {
- width: 70%;
- position: absolute;
- bottom: 70px;
- left: 20px;
- color: #f8f8f8;
- z-index: 10;
- letter-spacing: 1px;
- }
+.video-info {
+ width: 70%;
+ position: absolute;
+ bottom: 70px;
+ left: 20px;
+ color: #f8f8f8;
+ z-index: 10;
+ letter-spacing: 1px;
+}
- .action-buttons {
- position: absolute;
- right: 20px;
- bottom: 150px;
- display: flex;
- flex-direction: column;
- align-items: center;
- z-index: 10;
- }
+.action-buttons {
+ position: absolute;
+ right: 20px;
+ bottom: 150px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ z-index: 10;
+}
- .action-item {
- margin-bottom: 18px;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- color: #fff;
- }
+.action-item {
+ margin-bottom: 18px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ color: #fff;
+}
- .avatar-container {
- margin-bottom: 27px;
- position: relative;
- /* 涓虹粷瀵瑰畾浣嶇殑瀛愬厓绱犳彁渚涘畾浣嶄笂涓嬫枃 */
- width: 40px;
- height: 40px;
- display: inline-block;
- /* 浣垮鍣ㄦ牴鎹唴瀹硅皟鏁村ぇ灏� */
- }
+.avatar-container {
+ margin-bottom: 27px;
+ position: relative;
+ /* 涓虹粷瀵瑰畾浣嶇殑瀛愬厓绱犳彁渚涘畾浣嶄笂涓嬫枃 */
+ width: 40px;
+ height: 40px;
+ display: inline-block;
+ /* 浣垮鍣ㄦ牴鎹唴瀹硅皟鏁村ぇ灏� */
+}
- .avatar {
- border: 2px solid #FFFFFF;
- box-sizing: border-box;
- width: 100%;
- height: 100%;
- border-radius: 50%;
- /* 鍏抽敭灞炴�э紝璁剧疆涓�50%鍗冲彲瀹炵幇鍦嗗舰 */
- overflow: hidden;
- /* 纭繚鍥剧墖涓嶄細瓒呭嚭鍦嗗舰杈圭晫 */
- display: block;
- }
+.avatar {
+ border: 2px solid #FFFFFF;
+ box-sizing: border-box;
+ width: 100%;
+ height: 100%;
+ border-radius: 50%;
+ /* 鍏抽敭灞炴�э紝璁剧疆涓�50%鍗冲彲瀹炵幇鍦嗗舰 */
+ overflow: hidden;
+ /* 纭繚鍥剧墖涓嶄細瓒呭嚭鍦嗗舰杈圭晫 */
+ display: block;
+}
- .follow-icon {
- position: absolute;
- bottom: 0;
- /* 瀹氫綅鍒板簳閮� */
- left: 50%;
- /* 姘村钩灞呬腑寮�濮嬩綅缃� */
- transform: translate(-50%, 50%);
- /* 姘村钩灞呬腑骞跺悜涓嬬Щ鍔�50% */
+.follow-icon {
+ position: absolute;
+ bottom: 0;
+ /* 瀹氫綅鍒板簳閮� */
+ left: 50%;
+ /* 姘村钩灞呬腑寮�濮嬩綅缃� */
+ transform: translate(-50%, 50%);
+ /* 姘村钩灞呬腑骞跺悜涓嬬Щ鍔�50% */
- width: 18px;
- /* 鍥炬爣澶у皬 */
- height: 18px;
- background-color: #FF5A5F;
- /* 鍥炬爣鑳屾櫙鑹� */
- border-radius: 50%;
- display: flex;
- justify-content: center;
- align-items: center;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
- /* 杞诲井闃村奖 */
- }
+ width: 18px;
+ /* 鍥炬爣澶у皬 */
+ height: 18px;
+ background-color: #FF5A5F;
+ /* 鍥炬爣鑳屾櫙鑹� */
+ border-radius: 50%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+ /* 杞诲井闃村奖 */
+}
- .video-tag {
- margin-left: 5px;
- font-weight: bold;
- color: #eeeeee;
- }
+.video-tag {
+ margin-left: 5px;
+ font-weight: bold;
+ color: #eeeeee;
+}
- .video-author {
- font-size: 1.2em;
- }
+.video-author {
+ font-size: 1.2em;
+}
- /* 鍟嗗搧閾炬帴鎮寕灞傛牱寮� */
- .goods-link-warp {
- position: absolute;
- bottom: 160px;
- left: 20px;
- color: #f8f8f8;
- z-index: 10;
- }
+/* 鍟嗗搧閾炬帴鎮寕灞傛牱寮� */
+.goods-link-warp {
+ position: absolute;
+ bottom: 160px;
+ left: 20px;
+ color: #f8f8f8;
+ z-index: 10;
+}
- .goods-link {
- position: relative;
- margin: 20rpx 0;
- padding: 12rpx;
- background-color: rgba(255, 255, 255, 0.9);
- border-radius: 12rpx;
- box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
- }
+.goods-link {
+ position: relative;
+ margin: 20rpx 0;
+ padding: 12rpx;
+ background-color: rgba(255, 255, 255, 0.9);
+ border-radius: 12rpx;
+ box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
+}
- .goods-container {
- display: flex;
- align-items: center;
- }
+.goods-container {
+ display: flex;
+ align-items: center;
+}
- .goods-image {
- width: 120rpx;
- height: 120rpx;
- border-radius: 8rpx;
- margin-right: 20rpx;
- }
+.goods-image {
+ width: 120rpx;
+ height: 120rpx;
+ border-radius: 8rpx;
+ margin-right: 20rpx;
+}
- .goods-info {
- flex: 1;
- display: flex;
- flex-direction: column;
- justify-content: center;
- }
+.goods-info {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+}
- .goods-name {
- font-size: 28rpx;
- color: #333;
- font-weight: bold;
- display: -webkit-box;
- -webkit-line-clamp: 2;
- -webkit-box-orient: vertical;
- overflow: hidden;
- margin-bottom: 8rpx;
- }
+.goods-name {
+ font-size: 28rpx;
+ color: #333;
+ font-weight: bold;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ margin-bottom: 8rpx;
+}
- .price-section {
- display: flex;
- align-items: center;
- margin-bottom: 6rpx;
- }
+.price-section {
+ display: flex;
+ align-items: center;
+ margin-bottom: 6rpx;
+}
- .current-price {
- font-size: 32rpx;
- color: #ff2e4d;
- font-weight: bold;
- margin-right: 12rpx;
- }
+.current-price {
+ font-size: 32rpx;
+ color: #ff2e4d;
+ font-weight: bold;
+ margin-right: 12rpx;
+}
- .original-price {
- font-size: 28rpx;
- color: #999;
- text-decoration: line-through;
- }
+.original-price {
+ font-size: 28rpx;
+ color: #999;
+ text-decoration: line-through;
+}
- .sales-count {
- font-size: 22rpx;
- color: #999;
- }
+.sales-count {
+ font-size: 22rpx;
+ color: #999;
+}
- .buy-button {
- background: linear-gradient(to right, #ff5a5f, #ff2e4d);
- color: white;
- padding: 10rpx 28rpx;
- border-radius: 20rpx;
- font-size: 26rpx;
- font-weight: bold;
- }
+.buy-button {
+ background: linear-gradient(to right, #ff5a5f, #ff2e4d);
+ color: white;
+ padding: 10rpx 28rpx;
+ border-radius: 20rpx;
+ font-size: 26rpx;
+ font-weight: bold;
+}
- /* 璇勮寮圭獥鏍峰紡 */
- .comment-popup {
- background-color: #fff;
- border-radius: 20rpx 20rpx 0 0;
- padding-bottom: env(safe-area-inset-bottom);
- height: 60vh;
- display: flex;
- flex-direction: column;
- }
+/* 璇勮寮圭獥鏍峰紡 */
+.comment-popup {
+ background-color: #fff;
+ border-radius: 20rpx 20rpx 0 0;
+ padding-bottom: env(safe-area-inset-bottom);
+ height: 60vh;
+ display: flex;
+ flex-direction: column;
+}
- .popup-header {
- padding: 30rpx;
- display: flex;
- justify-content: space-between;
- align-items: center;
- border-bottom: 1rpx solid #f5f5f5;
- }
+.popup-header {
+ padding: 30rpx;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ border-bottom: 1rpx solid #f5f5f5;
+}
- .popup-title {
- font-size: 32rpx;
- font-weight: bold;
- }
+.popup-title {
+ font-size: 32rpx;
+ font-weight: bold;
+}
- .close-icon {
- /* font-size: 36rpx; */
- color: #999;
- }
+.close-icon {
+ /* font-size: 36rpx; */
+ color: #999;
+}
- .comment-list {
- flex: 1;
- padding: 0rpx 20rpx 20rpx 20rpx;
- box-sizing: border-box;
- height: calc(60vh - 260rpx);
- }
+.comment-list {
+ flex: 1;
+ padding: 0rpx 20rpx 20rpx 20rpx;
+ box-sizing: border-box;
+ height: calc(60vh - 260rpx);
+}
- .comment-item {
- display: flex;
- flex-direction: column;
- padding: 10rpx 0 20rpx 0;
- }
+.comment-item {
+ display: flex;
+ flex-direction: column;
+ padding: 10rpx 0 20rpx 0;
+}
- .comment-avatar {
- width: 70rpx;
- height: 70rpx;
- border-radius: 50%;
- margin-right: 10rpx;
- }
+.comment-avatar {
+ width: 70rpx;
+ height: 70rpx;
+ border-radius: 50%;
+ margin-right: 10rpx;
+}
- .comment-reply-avatar {
- width: 40rpx;
- height: 40rpx;
- border-radius: 50%;
- margin-right: 10rpx;
- }
+.comment-reply-avatar {
+ width: 40rpx;
+ height: 40rpx;
+ border-radius: 50%;
+ margin-right: 10rpx;
+}
- .comment-content {
- flex: 1;
- }
+.comment-content {
+ flex: 1;
+}
- .nickname {
- font-size: 28rpx;
- color: #666;
- display: block;
- margin-bottom: 10rpx;
- }
+.nickname {
+ font-size: 28rpx;
+ color: #666;
+ display: block;
+ margin-bottom: 10rpx;
+}
- .content {
- font-size: 28rpx;
- color: #333;
- display: block;
- margin-bottom: 10rpx;
- }
+.content {
+ font-size: 28rpx;
+ color: #333;
+ display: block;
+ margin-bottom: 10rpx;
+}
- .time {
- font-size: 28rpx;
- color: #999;
- }
+.time {
+ font-size: 28rpx;
+ color: #999;
+}
- .comment-input-area {
- display: flex;
- padding: 20rpx 30rpx;
- align-items: center;
- }
+.comment-input-area {
+ display: flex;
+ padding: 20rpx 30rpx;
+ align-items: center;
+}
- .comment-input {
- flex: 1;
- background-color: #fff;
- height: 80rpx;
- border: 1px solid #dcdcdc;
- border-radius: 40rpx;
- padding: 0 30rpx;
- font-size: 28rpx;
- }
+.comment-input {
+ flex: 1;
+ background-color: #fff;
+ height: 80rpx;
+ border: 1px solid #dcdcdc;
+ border-radius: 40rpx;
+ padding: 0 30rpx;
+ font-size: 28rpx;
+}
- .placeholder {
- color: #ccc;
- }
+.placeholder {
+ color: #ccc;
+}
- .submit-btn {
- margin-left: 20rpx;
- background-color: #07c160;
- color: #fff;
- border-radius: 40rpx;
- padding: 0 30rpx;
- height: 80rpx;
- line-height: 80rpx;
- font-size: 28rpx;
- }
+.submit-btn {
+ margin-left: 20rpx;
+ background-color: #07c160;
+ color: #fff;
+ border-radius: 40rpx;
+ padding: 0 30rpx;
+ height: 80rpx;
+ line-height: 80rpx;
+ font-size: 28rpx;
+}
- .loading,
- .empty {
- padding: 40rpx 0;
- text-align: center;
- color: #999;
- }
+.loading,
+.empty {
+ padding: 40rpx 0;
+ text-align: center;
+ color: #999;
+}
- .reply-list {
- margin-top: 20rpx;
- padding-left: 80rpx;
- }
+.reply-list {
+ margin-top: 20rpx;
+ padding-left: 80rpx;
+}
- .reply-op {
- margin-top: 10rpx;
- padding-left: 80rpx;
- display: flex;
- font-size: 28rpx;
- color: #333;
- }
+.reply-op {
+ margin-top: 10rpx;
+ padding-left: 80rpx;
+ display: flex;
+ font-size: 28rpx;
+ color: #333;
+}
- .reply-op-item {
- display: flex;
- align-items: center;
- height: 40rpx;
- }
+.reply-op-item {
+ display: flex;
+ align-items: center;
+ height: 40rpx;
+}
- .reply-item {
- display: flex;
- margin-bottom: 20rpx;
- }
+.reply-item {
+ display: flex;
+ margin-bottom: 20rpx;
+}
- .reply-content {
- flex: 1;
- }
+.reply-content {
+ flex: 1;
+}
- .reply-to {
- color: #576b95;
- margin: 0 10rpx;
- font-size: 28rpx;
- }
+.reply-to {
+ color: #576b95;
+ margin: 0 10rpx;
+ font-size: 28rpx;
+}
- .reply-title {
- display: flex;
- align-items: center;
- font-size: 28rpx;
- color: #333;
- }
+.reply-title {
+ display: flex;
+ align-items: center;
+ font-size: 28rpx;
+ color: #333;
+}
- .cancel-reply {
- margin-left: 20rpx;
- color: #576b95;
- font-size: 28rpx;
- padding: 6rpx 12rpx;
- background: #f5f5f5;
- border-radius: 20rpx;
- }
+.cancel-reply {
+ margin-left: 20rpx;
+ color: #576b95;
+ font-size: 28rpx;
+ padding: 6rpx 12rpx;
+ background: #f5f5f5;
+ border-radius: 20rpx;
+}
- .view-more-replies {
- color: #576b95;
- font-size: 28rpx;
- padding: 10rpx 0;
- padding-left: 80rpx;
- }
+.view-more-replies {
+ color: #576b95;
+ font-size: 28rpx;
+ padding: 10rpx 0;
+ padding-left: 80rpx;
+}
- .comment-footer,
- .reply-footer {
- display: flex;
- align-items: center;
- font-size: 28rpx;
- color: #999;
- }
+.comment-footer,
+.reply-footer {
+ display: flex;
+ align-items: center;
+ font-size: 28rpx;
+ color: #999;
+}
- .reply-btu {
- margin-left: 30rpx;
- }
+.reply-btu {
+ margin-left: 30rpx;
+}
- .thumbs-up {
- position: absolute;
- right: 20rpx;
- font-size: 32rpx;
- width: 120rpx;
- }
+.thumbs-up {
+ position: absolute;
+ right: 20rpx;
+ font-size: 32rpx;
+ width: 120rpx;
+}
- .textSideIcon {
- font-size: 36rpx;
- margin-left: 5rpx;
- }
+.textSideIcon {
+ font-size: 36rpx;
+ margin-left: 5rpx;
+}
- .line {
- margin-right: 10rpx;
- color: #cccccc;
- }
+.line {
+ margin-right: 10rpx;
+ color: #cccccc;
+}
- .thumbs-num {
- margin-left: 4rpx;
- }
+.thumbs-num {
+ margin-left: 4rpx;
+}
- .container {
- display: flex;
- flex-direction: column;
- align-items: center;
- position: absolute;
- bottom: 0;
- width: 100%;
- }
+.container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ position: absolute;
+ bottom: 0;
+ width: 100%;
+}
- .progress-bar {
- position: relative;
- width: 100%;
- height: 16px;
- background-color: #eee;
- overflow: hidden;
- }
+.progress-bar {
+ position: relative;
+ width: 100%;
+ height: 16px;
+ background-color: #eee;
+ overflow: hidden;
+}
- .progress-fill {
- position: absolute;
- left: 0;
- top: 0;
- height: 100%;
- background-color: lightgray;
- transition: width 0.1s;
- }
+.progress-fill {
+ position: absolute;
+ left: 0;
+ top: 0;
+ height: 100%;
+ background-color: lightgray;
+ transition: width 0.1s;
+}
- .process-warp {
- width: 100%;
- display: flex;
- flex-direction: column;
- align-items: center;
- }
+.process-warp {
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
- .progress-text {
- margin-top: 10px;
- font-size: 14px;
- color: #666;
- }
+.progress-text {
+ margin-top: 10px;
+ font-size: 14px;
+ color: #666;
+}
- .swiper-box {
- width: 100%;
- height: 1400rpx;
- }
+.swiper-box {
+ width: 100%;
+ height: 1400rpx;
+}
- .swiper-item {
- display: flex;
- justify-content: center;
- align-items: center;
- width: 100%;
- height: 100%;
- }
+.swiper-item {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ height: 100%;
+}
- .currentCategort {
- padding: 10rpx;
- }
+.currentCategort {
+ padding: 10rpx;
+}
- .typeNavigation {
- height: 100%;
- padding: 10rpx;
- box-sizing: border-box;
- }
+.typeNavigation {
+ height: 100%;
+ padding: 10rpx;
+ box-sizing: border-box;
+}
- .typeNavigationItem {
- padding: 24rpx;
- font-size: 28rpx;
- color: black;
- margin-top: 10rpx;
- border-radius: 12rpx;
- border: 1rpx solid gray;
- }
+.typeNavigationItem {
+ padding: 24rpx;
+ font-size: 28rpx;
+ color: black;
+ margin-top: 10rpx;
+ border-radius: 12rpx;
+ border: 1rpx solid gray;
+}
- .typeNavigationItemCheck {
- background-color: #42b993;
- color: #fff;
- border: 0;
- }
+.typeNavigationItemCheck {
+ background-color: #42b993;
+ color: #fff;
+ border: 0;
+}
- .container ::v-deep .navigationLeft .uni-drawer__content {
- height: 300rpx !important;
- top: 100rpx !important;
- background-color: lightpink !important;
+.container ::v-deep .navigationLeft .uni-drawer__content {
+ height: 300rpx !important;
+ top: 100rpx !important;
+ background-color: lightpink !important;
- }
+}
</style>
\ No newline at end of file
diff --git a/pages/mine/activity/reportActivity.vue b/pages/mine/activity/reportActivity.vue
index a1051f6..6e6e2ed 100644
--- a/pages/mine/activity/reportActivity.vue
+++ b/pages/mine/activity/reportActivity.vue
@@ -1,7 +1,7 @@
<template>
<view class="wrapper">
-
-
+ <top-bar selectedTitleIndex="activity" textColor="black" @changeTab="topBarChange" class="topBar"></top-bar>
+
<view style="height: 100rpx"></view>
<!-- 鍐呭鍖哄煙 -->
<scroll-view scroll-y class="content" style="height: 40vh;" @scrolltolower="loadMore" :lower-threshold="100">
@@ -47,9 +47,11 @@
</template>
<script>
+ import TopBar from "@/components/TopBar.vue";
import '@/components/uview-components/uview-ui';
import {getActivityReportList} from '@/api/activity.js';
export default {
+ components: {TopBar},
data() {
return {
columns: [
@@ -75,6 +77,17 @@
this.getActivityList();
},
methods: {
+ topBarChange(titleObj) {
+ if (titleObj.index === 'home') {
+ uni.switchTab({
+ url: titleObj.pagePath
+ });
+ } else {
+ uni.redirectTo({
+ url: titleObj.pagePath
+ });
+ }
+ },
/**
* 涓嬫媺鍒锋柊鏃�
*/
@@ -367,4 +380,10 @@
font-size: 28rpx;
}
}
-</style>
\ No newline at end of file
+ .topBar {
+ position: fixed;
+ top: 20rpx;
+ left: 20rpx;
+ z-index: 1000
+ }
+</style>
diff --git a/pages/order/fillorder.vue b/pages/order/fillorder.vue
index 251f7e7..7661f62 100644
--- a/pages/order/fillorder.vue
+++ b/pages/order/fillorder.vue
@@ -148,6 +148,11 @@
"
:span="3"
>
+<!-- <video v-if="val.goodsSku.goodsVideo" :src="val.goodsSku.goodsVideo"
+ style="width: 200rpx;height: 200rpx;border-radius: 10rpx;"
+ :initial-time="0"
+ :controls="false" object-fit="contain" :show-play-btn="false" :show-center-play-btn="false"
+ ></video> -->
<u-image
borderRadius="10rpx"
width="200rpx"
diff --git a/pages/order/myOrder.vue b/pages/order/myOrder.vue
index 91e50a5..865a80e 100644
--- a/pages/order/myOrder.vue
+++ b/pages/order/myOrder.vue
@@ -214,7 +214,7 @@
<script>
import '@/components/uview-components/uview-ui';
-import { getOrderList, cancelOrder, confirmReceipt } from "@/api/order.js";
+import { getOrderXcxList, cancelOrder, confirmReceipt } from "@/api/order.js";
import { getClearReason } from "@/api/after-sale.js";
import LiLiWXPay from "@/js_sdk/lili-pay/wx-pay.js";
export default {
@@ -436,7 +436,7 @@
loadData(index) {
this.params.pageNumber = this.navList[index].pageNumber;
// this.params.tag = this.orderStatus[index].orderStatus;
- getOrderList(this.params).then((res) => {
+ getOrderXcxList(this.params).then((res) => {
uni.stopPullDownRefresh();
if (!res.data.success) {
this.navList[index].loadStatus = "noMore";
diff --git a/pages/product/goods.vue b/pages/product/goods.vue
index fa701a1..10b03f2 100644
--- a/pages/product/goods.vue
+++ b/pages/product/goods.vue
@@ -344,21 +344,21 @@
// #endif
navbarListData: [
//瀵艰埅鏍忓垪琛ㄦ爮鏁版嵁
- {
- title: "棣栭〉",
- icon: "home-fill",
- ___type: "other",
- },
+ // {
+ // title: "棣栭〉",
+ // icon: "home-fill",
+ // ___type: "other",
+ // },
{
title: "璐墿杞�",
icon: "bag-fill",
___type: "other",
},
- {
- title: "鎼滅储",
- icon: "search",
- ___type: "category",
- },
+ // {
+ // title: "鎼滅储",
+ // icon: "search",
+ // ___type: "category",
+ // },
{
title: "涓汉涓績",
icon: "account-fill",
diff --git a/pages/supplier/suppler-order/suppler-order.vue b/pages/supplier/suppler-order/suppler-order.vue
new file mode 100644
index 0000000..df4e95d
--- /dev/null
+++ b/pages/supplier/suppler-order/suppler-order.vue
@@ -0,0 +1,666 @@
+<template>
+ <view class="content">
+ <view class="navbar">
+ <view
+ v-for="(item, index) in navList"
+ :key="index"
+ class="nav-item"
+ :class="{ current: tabCurrentIndex === index }"
+ @click="tabClick(index)"
+ >{{ item.text }}</view
+ >
+ </view>
+ <swiper
+ :current="tabCurrentIndex"
+ class="swiper-box"
+ duration="300"
+ @change="changeTab"
+ >
+ <swiper-item
+ class="tab-content"
+ v-for="(tabItem, tabIndex) in navList"
+ :key="tabIndex"
+ >
+ <scroll-view
+ class="list-scroll-content"
+ scroll-y
+ @scrolltolower="loadData(tabIndex)"
+ >
+ <!-- 绌虹櫧椤� -->
+ <u-empty
+ text="鏆傛棤璁㈠崟"
+ mode="list"
+ v-if="tabItem.loaded === true && tabItem.orderList.length === 0"
+ ></u-empty>
+ <!-- 璁㈠崟鍒楄〃 -->
+ <view
+ class="seller-view"
+ :key="oderIndex"
+ v-for="(order, oderIndex) in tabItem.orderList"
+ >
+ <!-- 搴楅摵鍚嶇О -->
+ <view class="seller-info u-flex u-row-between">
+ <view class="seller-name wes" >
+ <view class="name wes">{{ order.storeName }}</view>
+ </view>
+ <view class="order-sn">{{
+ order.orderStatus | orderStatusList
+ }}</view>
+ </view>
+ <view>
+ <view>
+ <view
+ class="goods-item-view"
+ >
+ <view
+ class="goods-img"
+ v-for="(goods, goodsIndex) in order.orderItems"
+ :key="goodsIndex"
+ >
+ <u-image
+ border-radius="6"
+ width="100%"
+ height="100%"
+ :src="goods.image"
+ ></u-image>
+ </view>
+ <view class="goods-info">
+ <view
+ v-if="order.orderItems.length <= 1"
+ class="goods-title u-line-2"
+ >{{ order.groupName }}</view
+ >
+ <view
+ v-if="order.orderItems.length <= 1"
+ class="goods-price"
+ >
+ 锟{ order.flowPrice | unitPrice }}
+ </view>
+ </view>
+ <view v-if="order.orderItems.length <= 1" class="goods-num">
+ <view>x{{ order.groupNum }}</view>
+ </view>
+ </view>
+ </view>
+ <view class="btn-view u-flex u-row-between">
+ <view class="description">
+ <!-- 绛夊緟浠樻 -->
+ <div v-if="order.payStatus === 'PAID'">宸蹭粯閲戦:</div>
+ <div v-else>搴斾粯閲戦:</div>
+ <div class="price">锟{ order.flowPrice | unitPrice }}</div>
+ </view>
+ <view class="goods-btn flex flex-a-c">
+ <!-- 鍏ㄩ儴 -->
+ <view
+ ripple
+ class="rebuy-btn"
+ shape="circle"
+ size="mini"
+ v-if="order.allowOperationVO.pay"
+ @click="selectPhone(order.sn)"
+ >鏌ョ湅鑱旂郴鏂瑰紡</view
+ >
+ <view
+ ripple
+ class="rebuy-btn"
+ shape="circle"
+ size="mini"
+ v-if="order.orderStatus==='UNDELIVERED'"
+ >鍙戣揣</view
+ >
+ <!-- 绛夊緟鏀惰揣 -->
+ <view
+ ripple
+ shape="circle"
+ class="rebuy-btn"
+ size="mini"
+ v-if="order.allowOperationVO.showLogistics"
+ @click="navigateToLogistics(order)"
+ >
+ 鏌ョ湅鐗╂祦
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+ <uni-load-more :status="tabItem.loadStatus"></uni-load-more>
+ </scroll-view>
+ </swiper-item>
+ </swiper>
+ </uni-popup>
+ </view>
+</template>
+
+<script>
+import '@/components/uview-components/uview-ui';
+import { getOrderXcxList, cancelOrder, confirmReceipt ,getOrderDetail} from "@/api/order.js";
+import { getClearReason } from "@/api/after-sale.js";
+import LiLiWXPay from "@/js_sdk/lili-pay/wx-pay.js";
+export default {
+
+ data() {
+ return {
+ lightColor: this.$lightColor,
+ tabCurrentIndex: 0, //瀵艰埅鏍忕储寮�
+ userInfo:{
+ name:'',
+ phone:'',
+ address:''
+ },
+ navList: [
+ //瀵艰埅鏍弆ist
+ // {
+ // state: 0,
+ // text: "鍏ㄩ儴",
+ // loadStatus: "more",
+ // orderList: [],
+ // pageNumber: 1,
+ // },
+ {
+ state: 1,
+ text: "寰呬粯娆�",
+ loadStatus: "more",
+ orderList: [],
+ pageNumber: 1,
+ },
+ {
+ state: 2,
+ text: "寰呭彂璐�",
+ loadStatus: "more",
+ orderList: [],
+ pageNumber: 1,
+ },
+ {
+ state: 3,
+ text: "宸插彂璐�",
+ loadStatus: "more",
+ orderList: [],
+ pageNumber: 1,
+ },
+ // {
+ // state: 4,
+ // text: "宸插畬鎴�",
+ // loadStatus: "more",
+ // orderList: [],
+ // pageNumber: 1,
+ // },
+ // {
+ // state: 5,
+ // text: "宸插彇娑�",
+ // loadStatus: "more",
+ // orderList: [],
+ // pageNumber: 1,
+ // },
+ ],
+ status: "", //鎺ユ敹瀵艰埅鏍忕姸鎬�
+ params: {
+ pageNumber: 1,
+ pageSize: 10,
+ tag: "WAIT_PAY",
+ },
+ orderStatus: [
+ //璁㈠崟鐘舵��
+ // {
+ // orderStatus: "ALL", //鍏ㄩ儴
+ // },
+ {
+ orderStatus: "WAIT_PAY", //浠d粯娆�
+ },
+ {
+ orderStatus: "WAIT_SHIP",
+ },
+ {
+ orderStatus: "WAIT_ROG", //寰呮敹璐�
+ },
+ // {
+ // orderStatus: "COMPLETE", //宸插畬鎴�
+ // },
+ // {
+ // orderStatus: "CANCELLED", //宸插彇娑�
+ // },
+ // {
+ // orderStatus: "STAY_PICKED_UP", //寰呰嚜鎻�
+ // },
+ ],
+ cancelShow: false, //鏄惁鏄剧ず鍙栨秷
+ orderSn: "", //ordersn
+ reason: "", //鍙栨秷鍘熷洜
+ cancelList: "", //鍙栨秷鍒楄〃
+ rogShow: false, //鏄剧ず鏄惁鏀惰揣
+ };
+ },
+
+ /**
+ * 璺宠浆鍒颁釜浜轰腑蹇�
+ */
+ onBackPress(e) {
+ if (e.from == "backbutton") {
+ uni.switchTab({
+ url: "/pages/tabbar/user/my",
+ });
+ return true; //闃绘榛樿杩斿洖琛屼负
+ }
+ },
+ onPullDownRefresh() {
+ if (this.tabCurrentIndex) {
+ this.initData(this.tabCurrentIndex);
+ } else {
+ this.initData(0);
+ }
+ // this.loadData(this.status);
+ },
+ onShow() {
+ if(this.$options.filters.tipsToLogin()){
+ if (!this.tabCurrentIndex) {
+ this.initData(0);
+ }
+ }
+ // this.loadData(this.status);
+ },
+
+ onLoad(options) {
+ /**
+ * 淇app绔偣鍑婚櫎鍏ㄩ儴璁㈠崟澶栫殑鎸夐挳杩涘叆鏃朵笉鍔犺浇鏁版嵁鐨勯棶棰�
+ * 鏇挎崲onLoad涓嬩唬鐮佸嵆鍙�
+ */
+ let status = Number(options.status);
+ this.status = status;
+
+ this.tabCurrentIndex = status;
+ // if (status == 0) {
+ // this.loadData(status);
+ // }
+ },
+
+ watch: {
+ /**鐩戝惉鏇存敼璇锋眰鏁版嵁 */
+ tabCurrentIndex(val) {
+ this.params.tag = this.orderStatus[val].orderStatus;
+ //鍒囨崲鏍囩椤靛皢鎵�鏈夌殑椤垫暟閮介噸缃负1
+ this.navList.forEach((res) => {
+ res.pageNumber = 1;
+ res.loadStatus = "more";
+ res.orderList = [];
+ });
+ this.loadData(val);
+ },
+ },
+ methods: {
+ async selectPhone(sn){
+ const orderInfo = await getOrderDetail(sn)
+ console.log('----------------->',orderInfo)
+ this.userInfo = {};
+ this.userInfo.name = orderInfo.data.result.order.consigneeName
+ this.userInfo.phone =orderInfo.data.result.order.consigneeMobile
+ this.userInfo.address = orderInfo.data.result.order.consigneeAddressPath
+
+ uni.showModal({
+ title:"鐢ㄦ埛鑱旂郴鐢佃瘽",
+ content:orderInfo.data.result.order.consigneeMobile
+ })
+
+ },
+ /**
+ * 鍒濆鍖栨暟鎹�
+ */
+ initData(index) {
+ this.navList[index].pageNumber = 1;
+ this.navList[index].loadStatus = "more";
+ this.navList[index].orderList = [];
+ this.loadData(index);
+ },
+
+ /**
+ * 鑾峰彇璁㈠崟鍒楄〃
+ */
+ loadData(index) {
+ this.params.pageNumber = this.navList[index].pageNumber;
+ // this.params.tag = this.orderStatus[index].orderStatus;
+ getOrderXcxList(this.params).then((res) => {
+ uni.stopPullDownRefresh();
+ if (!res.data.success) {
+ this.navList[index].loadStatus = "noMore";
+ return false;
+ }
+ let orderList = res.data.result.records;
+ if (orderList.length == 0) {
+ this.navList[index].loadStatus = "noMore";
+ } else if (orderList.length < 10) {
+ this.navList[index].loadStatus = "noMore";
+ }
+ if (orderList.length > 0) {
+ this.navList[index].orderList =
+ this.navList[index].orderList.concat(orderList);
+ this.navList[index].pageNumber += 1;
+ }
+ });
+ },
+ //swiper 鍒囨崲鐩戝惉
+ changeTab(e) {
+ this.tabCurrentIndex = e.target.current;
+ },
+ //椤堕儴tab鐐瑰嚮
+ tabClick(index) {
+ this.tabCurrentIndex = index;
+ },
+
+ //璁㈠崟鐘舵�佹枃瀛楀拰棰滆壊
+ orderStateExp(state) {
+ let stateTip = "",
+ stateTipColor = this.$lightColor;
+ switch (+state) {
+ case 1:
+ stateTip = "寰呬粯娆�";
+ break;
+ case 2:
+ stateTip = "寰呭彂璐�";
+ break;
+ case 9:
+ stateTip = "璁㈠崟宸插叧闂�";
+ stateTipColor = "#909399";
+ break;
+
+ //鏇村鑷畾涔�
+ }
+ return {
+ stateTip,
+ stateTipColor,
+ };
+ },
+ /**
+ * 閫夋嫨鍙栨秷鍘熷洜
+ */
+ reasonChange(reason) {
+ this.reason = reason;
+ },
+
+ /**
+ * 鎻愪氦鍙栨秷璁㈠崟锛堟湭浠樻锛�
+ */
+ submitCancel() {
+ cancelOrder(this.orderSn, { reason: this.reason }).then((res) => {
+ if (res.data.success) {
+ uni.showToast({
+ title: "璁㈠崟宸插彇娑�",
+ duration: 2000,
+ icon: "none",
+ });
+ this.initData(this.tabCurrentIndex);
+
+ this.cancelShow = false;
+ } else {
+ uni.showToast({
+ title: res.data.message,
+ duration: 2000,
+ icon: "none",
+ });
+ this.cancelShow = false;
+ }
+ });
+ },
+
+ /**
+ * 纭鏀惰揣鏄剧ず
+ */
+ onRog(sn) {
+ this.orderSn = sn;
+ this.rogShow = true;
+ },
+
+ /**
+ * 鐐瑰嚮纭鏀惰揣
+ */
+ confirmRog() {
+ confirmReceipt(this.orderSn).then((res) => {
+ if (res.data.code == 200) {
+ uni.showToast({
+ title: "宸茬‘璁ゆ敹璐�",
+ duration: 2000,
+ icon: "none",
+ });
+ this.initData(this.tabCurrentIndex);
+ this.rogShow = false;
+ }
+ });
+ },
+
+ /**
+ * 璇勪环鍟嗗搧
+ */
+ onComment(sn) {
+ uni.navigateTo({
+ url: "./evaluate/myEvaluate",
+ });
+ },
+
+ /**
+ * 閲嶆柊璐拱
+ */
+ reBuy(order) {
+ console.log(order);
+ return;
+ uni.navigateTo({
+ url:
+ "/pages/product/goods?id=" + order.id + "&goodsId=" + order.goodsId,
+ });
+ },
+
+ /**
+ * 鏌ョ湅鐗╂祦
+ */
+ navigateToLogistics(order) {
+ uni.navigateTo({
+ url:
+ "/pages/mine/msgTips/packageMsg/logisticsDetail?order_sn=" + order.sn,
+ });
+ },
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+page,
+.content {
+ background: $page-color-base;
+ height: 100%;
+}
+
+.swiper-box {
+ height: calc(100vh - 40px);
+ // #ifdef H5
+ height: calc(100vh - 40px - 44px);
+ // #endif
+}
+
+.list-scroll-content {
+ height: 100%;
+}
+
+.navbar {
+ display: flex;
+ height: 40px;
+ padding: 0 5px;
+ background: #fff;
+ box-shadow: 0 1px 5px rgba(0, 0, 0, 0.06);
+ position: relative;
+ z-index: 10;
+
+ .nav-item {
+ flex: 1;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100%;
+ font-size: 26rpx;
+ color: $font-color-light;
+ position: relative;
+
+ &.current {
+ color: $main-color;
+
+ &:after {
+ content: "";
+ position: absolute;
+ left: 50%;
+ bottom: 0;
+ transform: translateX(-50%);
+ width: 44px;
+ height: 0;
+ border-bottom: 2px solid $main-color;
+ }
+ }
+ }
+}
+
+.uni-swiper-item {
+ height: auto;
+}
+
+.seller-view {
+ border-radius: 20rpx;
+ background-color: #fff;
+ margin: 20rpx 0rpx;
+
+ .seller-info {
+ height: 70rpx;
+ padding: 0 20rpx;
+
+ .seller-name {
+ flex:10;
+ font-size: 28rpx;
+ font-weight: 600;
+ display: flex;
+ flex-direction: row;
+
+ .name {
+ margin-left: 15rpx;
+ margin-top: -2rpx;
+ }
+ }
+
+ .order-sn {
+ flex:2;
+ width:120rpx;
+ text-align: center;
+ color: $aider-light-color;
+ font-size: 26rpx;
+ }
+ }
+
+ .goods-item-view {
+ display: flex;
+ flex-wrap: wrap;
+ flex-direction: row;
+ padding: 10rpx 20rpx;
+
+ .goods-img {
+ width: 131rpx;
+ height: 131rpx;
+ margin-right: 10rpx;
+ margin-bottom: 10rpx;
+ }
+
+ .goods-info {
+ padding-left: 30rpx;
+ flex: 1;
+
+ .goods-title {
+ margin-bottom: 10rpx;
+ color: #333333;
+ }
+
+ .goods-specs {
+ font-size: 24rpx;
+ margin-bottom: 10rpx;
+ color: #cccccc;
+ }
+
+ .goods-price {
+ font-size: 28rpx;
+ margin-bottom: 10rpx;
+ color: $aider-light-color;
+ }
+ }
+
+ .goods-num {
+ width: 60rpx;
+ color: $main-color;
+ }
+ }
+
+ .btn-view {
+ padding: 25rpx 30rpx;
+ font-size: 26rpx;
+
+ .description {
+ display: flex;
+ color: #909399;
+ size: 24rpx;
+ flex: 1;
+ .price {
+ color: $main-color;
+
+ }
+ }
+ }
+}
+
+.cancel-popup {
+ .header {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ margin: 15rpx 0rpx;
+ }
+
+ .body {
+ padding: 30rpx;
+
+ .title {
+ font-weight: 600;
+ }
+
+ .value {
+ display: flex;
+ flex-direction: column;
+ margin: 20rpx 0;
+ .radio-view {
+ margin: 20rpx 0rpx;
+ }
+ }
+ }
+
+ .footer {
+ text-align: center;
+ }
+}
+.goods-btn{
+ display: flex;
+}
+.cancel-btn,.pay-btn,.rebuy-btn{
+ text-align: center;
+ margin-left: 15rpx;
+ font-size: 24rpx;
+ padding: 14rpx 20rpx;
+ border-radius: 100px;
+
+}
+.cancel-btn {
+ color: #333639 !important;
+ background: rgba(46, 51, 56, .05) !important;
+}
+
+.pay-btn {
+
+ background-color: $light-color !important;
+
+ color: #ffffff !important;
+}
+
+.rebuy-btn {
+ color: $light-color !important;
+ border-color: $light-color !important;
+ background-color: #ffffff !important;
+}
+</style>
+
diff --git a/pages/tabbar/cart/cartList.vue b/pages/tabbar/cart/cartList.vue
index d15dfdc..c6e1e61 100644
--- a/pages/tabbar/cart/cartList.vue
+++ b/pages/tabbar/cart/cartList.vue
@@ -68,7 +68,12 @@
</u-checkbox-group>
<span class="invalid" v-else style="font-size: 24rpx">澶辨晥</span>
</view>
- <u-image border-radius="10" :fade="true" @click="navigateToGoods(skuItem)" width="160rpx" height="160rpx"
+<!-- <video border-radius="10" :fade="true" @click="navigateToGoods(skuItem)"
+ v-if="skuItem.goodsSku.goodsVideo" :src="skuItem.goodsSku.goodsVideo"
+ style="width: 160rpx;height: 160rpx;"
+ :initial-time="0"
+ :controls="false" object-fit="contain" :show-play-btn="false" :show-center-play-btn="false"/> -->
+ <u-image border-radius="10" :fade="true" @click="navigateToGoods(skuItem)" width="160rpx" height="160rpx"
:src="skuItem.goodsSku.thumbnail" />
</view>
<view class="goods-content">
diff --git a/pages/tabbar/index/home.vue b/pages/tabbar/index/home.vue
index 1c56703..9aebf49 100644
--- a/pages/tabbar/index/home.vue
+++ b/pages/tabbar/index/home.vue
@@ -1,11 +1,15 @@
<template>
<view class="video-container">
+ <top-bar selectedTitleIndex="home" textColor="white" @changeTab="topBarChange" class="topBar"></top-bar>
+ <!-- 瑙嗛鍔犺浇 -->
+ <zero-loading v-show="videoLoading" type="circle" color="#0ebd57" text=""></zero-loading>
<!-- 瑙嗛鍒楄〃 -->
<swiper
class="video-swiper"
vertical
:current="currentIndex"
@change="onSwiperChange"
+ :duration="250"
easing-function="linear"
>
<swiper-item
@@ -25,14 +29,16 @@
<image src="/static/video/play.png" style="width: 45px;height: 45px" mode="aspectFit"></image>
</view>
<video
+ v-if="index >= currentIndex - videoLiveOffset && index <= currentIndex + videoLiveOffset"
:id="'video'+index"
:ref="'video'+index"
:src="item.videoUrl"
- :autoplay="false"
+ :autoplay="index === currentIndex"
:controls="false"
:loop="true"
:object-fit="item.objectFit"
:enable-progress-gesture="false"
+ :show-center-play-btn="false"
class="video-item"
@play="onPlay(item.id, index)"
@pause="onPause(index)"
@@ -40,12 +46,13 @@
@click="togglePlay(index)"
@timeupdate="onTimeUpdate($event)"
@loadedmetadata="onLoadedMetadata($event)"
+ @waiting="videoWaiting(index)"
></video>
<!-- 鑷畾涔夋帶鍒舵潯 -->
<view
- @touchstart="handleTouchStart"
- @touchmove="handleTouchMove"
- @touchend="handleTouchEnd"
+ @touchstart.stop="handleTouchStart"
+ @touchmove.stop="handleTouchMove"
+ @touchend.stop="handleTouchEnd"
class="container">
<!-- 杩涘害鏉� - 鏁翠釜鍖哄煙鍙嫋鍔� -->
<view class="process-warp" :style="{ opacity: showProcess ? 1 : 0 }">
@@ -241,7 +248,10 @@
import { silentLogin } from "@/api/connect.js";
import { getUserInfo } from "@/api/members";
import storage from "@/utils/storage.js";
+import TopBar from "@/components/TopBar.vue";
+
export default {
+ components: {TopBar},
computed: {
hasPlayTime() {
return this.sliderFormatTime(this.progress > 0 ? this.duration * this.progress / 100 : 0);
@@ -300,13 +310,11 @@
startPlayTime: 0 // 杩欎釜瑙嗛浠庝粈涔堟椂鍊欏紑濮嬫挱鏀剧殑
},
currentVideoIsPlaying: true, // 褰撳墠瑙嗛鏄惁姝e湪鎾斁
- isFullScreen: false,
- windowHeight: 0,
currentIndex: 0, // 褰撳墠鎾斁鐨勮棰戠储寮�
+ videoLoading: false, // 瑙嗛缂撳啿涓�
videoList: [], // 瑙嗛鍒楄〃鏁版嵁
- videoContexts: [], // 瑙嗛涓婁笅鏂囧璞¢泦鍚�
videoBufferOffset: 0.1 ,// 瑙嗛棰勫姞杞藉弬鏁�
- videoLiveOffset: 5, // 淇濈暀褰撳墠瑙嗛鍓嶅悗鍚勫灏戜釜瑙嗛涓婁笅鏂�
+ videoLiveOffset: 2, // 淇濈暀褰撳墠瑙嗛鍓嶅悗鍚勫灏戜釜瑙嗛涓婁笅鏂�
touchXY: { // 鐩戝惉宸︽粦鍙虫粦
startX: 0,
endX: 0,
@@ -375,6 +383,17 @@
}
},
methods: {
+ topBarChange(titleObj) {
+ if (titleObj.index === 'home') {
+ uni.switchTab({
+ url: titleObj.pagePath
+ });
+ } else {
+ uni.redirectTo({
+ url: titleObj.pagePath
+ });
+ }
+ },
// 闈欓粯鐧诲綍
wxSilentLogin(callback) {
//鑾峰彇code
@@ -662,56 +681,6 @@
}
})
},
- // 鍒濆鍖栬棰戜笂涓嬫枃
- initVideoContexts() {
- const start = Math.max(0, this.currentIndex - this.videoLiveOffset);
- const end = Math.min(this.currentIndex + this.videoLiveOffset, this.videoList.length - 1);
- let contextsLength = this.videoContexts.length;
- if (contextsLength === 0) {
- // 绗竴娆″垵濮嬪寲
- for (let i = 0; i < this.videoList.length; i++) {
- if (i < start || i > end) {
- this.videoContexts.push(null)
- } else {
- let videoContent = uni.createVideoContext(`video${i}`, this);
- videoContent.seek(this.videoBufferOffset);
- videoContent.pause();
- this.videoContexts.push(videoContent);
- }
- }
- } else {
- for (let i = 0; i < this.videoList.length; i++) {
- contextsLength = this.videoContexts.length
- if (contextsLength - 1 >= i) {
- // 濡傛灉宸茬粡鏄痭ull浜嗗氨涓嶇敤绠★紝鍥犱负瑙嗛鍔犺浇鍙細鍦ㄥ悗闈ush锛屽墠闈㈠凡缁忚缃负null鍒欐棤闇�澶勭悊
- if (this.videoContexts[i] == null) {
- continue
- }
- // 瓒呭嚭鍙鍖栬寖鍥寸殑瑙嗛鐩存帴閲婃斁璧勬簮锛屽苟缃负null
- if (i < start || i > end) {
- if (this.videoContexts[i]) {
- this.videoContexts[i].stop();
- this.videoContexts[i] = null
- }
- }
- } else {
- if (i < start || i > end) {
- this.videoContexts.push(null);
- } else {
- let videoContent = uni.createVideoContext(`video${i}`, this);
- videoContent.seek(this.videoBufferOffset);
- videoContent.pause();
- this.videoContexts.push(videoContent);
- }
- }
- }
- }
- // 灏嗗綋鍓嶈棰戣缃负鎾斁
- if (this.videoContexts[this.currentIndex]) {
- this.videoContexts[this.currentIndex].play()
- }
-
- },
// 鍔犺浇瑙嗛鏁版嵁
async loadVideos() {
@@ -730,9 +699,6 @@
),
];
}
- this.$nextTick(() => {
- this.initVideoContexts();
- });
this.loading = false;
if(res.data.data.length < this.videoQuery.pageSize) {
this.videoNoMore = true;
@@ -745,6 +711,7 @@
// 婊戝姩鍒囨崲瑙嗛
onSwiperChange(e) {
+ this.videoLoading = false
// 濡傛灉瑙嗛澶勪簬鏆傚仠鐘舵�佸線涓嬪埛瑙嗛锛岄偅涔堥渶瑕佸啀璁$畻涓�娆℃殏鍋滄椂闂�
if(!this.currentVideoIsPlaying) {
if(this.startPauseTime !== 0) {
@@ -756,49 +723,23 @@
this.savePlayRecord()
const oldIndex = this.currentIndex;
this.currentIndex = e.detail.current;
-
+ const videoContext = uni.createVideoContext(`video${oldIndex}`, this);
// 鏆傚仠涓婁竴涓棰�
- if (this.videoContexts[oldIndex]) {
- this.videoContexts[oldIndex].pause();
- }
-
+ videoContext.pause();
this.startPauseTime = 0;
// 璁剧疆褰撳墠鎾斁瑙嗛鐨勬�绘椂闀�
this.duration = this.videoList[this.currentIndex].videoDuration;
this.formartDuration = this.sliderFormatTime(this.duration);
- // 鎾斁褰撳墠瑙嗛
- if (this.videoContexts[this.currentIndex]) {
- this.videoContexts[this.currentIndex].play();
- }
- this.clearVideoContext()
- },
- // 娓呴櫎瓒呭嚭瑙嗛鍙鍖栧尯鍩熺殑瑙嗛涓婁笅鏂�
- async clearVideoContext() {
- // 瀵硅秴鍑哄彲瑙嗗寲鍖哄煙鐨勮棰戜笂涓嬫枃鍋氶攢姣佸鐞�
- const start = Math.max(0, this.currentIndex - this.videoLiveOffset);
- const end = Math.min(this.currentIndex + this.videoLiveOffset, this.videoList.length - 1);
- for (let i = 0; i < this.videoContexts.length; i++) {
- if (i < start || i > end) {
- if (this.videoContexts[i]) {
- this.videoContexts[i].stop();
- this.videoContexts[i] = null
- }
- } else {
- if (this.videoContexts[i] == null) {
- let videoContent = uni.createVideoContext(`video${i}`, this);
- videoContent.seek(this.videoBufferOffset);
- videoContent.pause();
- this.videoContexts[i] = videoContent;
- }
- }
- }
+ // 鎾斁褰撳墠瑙嗛
+ const videoContext1 = uni.createVideoContext(`video${this.currentIndex}`, this);
+ videoContext1.play()
// 濡傛灉鍓╀綑瑙嗛涓嶈冻锛岃Е鍙戣姹傝幏鍙栨洿澶氳棰�
if (this.videoList.length - 1 < this.currentIndex + this.videoLiveOffset) {
this.loadVideos()
}
- },
+ },
// 寮�濮嬭Е鎽�
handleSwiperStart(e) {
@@ -808,12 +749,15 @@
},
// 瑙︽懜涓�
handleSwiperMove(e) {
- console.log("瑙︽懜涓�", e);
this.touchXY.endX = e.touches[0].pageX
this.touchXY.endY = e.touches[0].pageY
},
// 缁撴潫瑙︽懜
handleSwiperEnd(item) {
+ // 闃叉婊戝姩婊氬姩鏉′篃瑙﹀彂璺宠浆
+ if (this.showProcess) {
+ return
+ }
const diffX = this.touchXY.endX - this.touchXY.startX
const diffY = this.touchXY.endY - this.touchXY.startY
@@ -861,18 +805,16 @@
},
// 鍗曞嚮灞忓箷锛氭殏鍋滄垨缁х画鎾斁
togglePlay(index) {
- console.log("鍗曞嚮瑙嗛", index, this.videoContexts);
+ console.log("鍗曞嚮瑙嗛", index);
+ const videoContext = uni.createVideoContext(`video${index}`, this);
if(this.currentVideoIsPlaying) {
- this.videoContexts[index].pause();
+ videoContext.pause();
} else {
- this.videoContexts[index].play();
+ videoContext.play();
}
},
// 瑙嗛鎾斁浜嬩欢
onPlay(id, index) {
- this.getBarRect()
- this.progress = 0
- console.log(id, index, "瑙﹀彂鎾斁");
if(index === this.currentIndex) {
this.currentVideoIsPlaying = true;
if(! this.duration) {
@@ -881,9 +823,11 @@
this.formartDuration = this.sliderFormatTime(this.duration);
}
} else {
- this.currentVideoIsPlaying = false;
return
}
+ this.getBarRect()
+ this.progress = 0
+ console.log(id, index, "瑙﹀彂鎾斁");
this.playRecord.videoId = id;
// 娌″垵濮嬪寲鎵嶈祴鍊硷紝鍥犱负涓�涓棰戦噸澶嶆挱鏀緊nPlay浼氶噸澶嶈Е鍙�
if(this.playRecord.startPlayTime === 0) {
@@ -893,7 +837,7 @@
const duration = Date.now() - this.startPauseTime
this.totalPauseTime += duration
}
-
+ this.videoLoading = false
},
// 瑙嗛鏆傚仠浜嬩欢
@@ -901,11 +845,8 @@
console.log(index, "瑙﹀彂鏆傚仠");
if(index === this.currentIndex) {
this.currentVideoIsPlaying = false;
- } else {
- this.currentVideoIsPlaying = true;
- return
+ this.startPauseTime = Date.now()
}
- this.startPauseTime = Date.now()
},
// 瑙嗛缁撴潫浜嬩欢
onEnded(index) {
@@ -914,6 +855,7 @@
// 璁板綍鎾斁鏃堕暱
onTimeUpdate(e) {
+ this.videoLoading = false
this.playRecord.playAt = e.detail.currentTime;
this.currentTime = e.detail.currentTime;
@@ -926,7 +868,8 @@
this.startProgress = this.progress; // 璁板綍寮�濮嬫椂鐨勮繘搴�
this.startX = e.touches[0].pageX;
console.log("璁板綍寮�濮嬫椂鐨勮繘搴�", this.startProgress);
- this.videoContexts[this.currentIndex].pause()
+ const videoContext = uni.createVideoContext(`video${this.currentIndex}`, this);
+ videoContext.pause()
// this.updateProgress(e);
},
@@ -934,7 +877,6 @@
handleTouchMove(e) {
if (!this.isDragging || !this.barWidth) return;
clearTimeout(this.processHidenTimer)
- this.videoContexts[this.currentIndex].pause()
this.updateProgress(e);
},
@@ -942,8 +884,9 @@
handleTouchEnd() {
this.isDragging = false;
console.log("婊戝姩缁撴潫", this.duration * this.progress);
- this.videoContexts[this.currentIndex].seek(this.duration * this.progress / 100)
- this.videoContexts[this.currentIndex].play()
+ const videoContext = uni.createVideoContext(`video${this.currentIndex}`, this);
+ videoContext.seek(this.duration * this.progress / 100)
+ videoContext.play()
this.processHidenTimer = setTimeout(() => {
this.showProcess = false;
}, 1000);
@@ -959,7 +902,6 @@
// 灏嗗儚绱犺窛绂昏浆鎹负杩涘害澧為噺
const deltaProgress = (deltaX / this.barWidth) * 100;
- console.log("杩涘害澧為噺", deltaProgress);
// 璁$畻鏂拌繘搴� = 寮�濮嬫椂鐨勮繘搴� + 婊戝姩澧為噺
let newProgress = this.startProgress + deltaProgress;
@@ -967,6 +909,13 @@
newProgress = Math.max(0, Math.min(100, newProgress));
this.progress = newProgress;
+ },
+ // 瑙嗛缂撳啿
+ videoWaiting(index) {
+ if (index === this.currentIndex) {
+ console.log("瑙嗛缂撳啿涓�傘�傘��");
+ this.videoLoading = true;
+ }
},
// 鑾峰彇瑙嗛鎬绘椂闀�
onLoadedMetadata(e) {
@@ -1015,7 +964,7 @@
.video-item {
width: 100%;
height: 100%;
- object-fit: cover;
+ /* object-fit: cover; */
}
.play-icon {
position: absolute;
@@ -1427,4 +1376,10 @@
.custom-share-btn::after {
border: none;
}
+ .topBar {
+ position: fixed;
+ top: 20rpx;
+ left: 20rpx;
+ z-index: 1000
+ }
</style>
diff --git a/pages/tabbar/user/utils/tool.vue b/pages/tabbar/user/utils/tool.vue
index 1520f0e..2849927 100644
--- a/pages/tabbar/user/utils/tool.vue
+++ b/pages/tabbar/user/utils/tool.vue
@@ -131,7 +131,10 @@
<image src="/static/mine/setting.png" mode=""></image>
<view>鍟嗗搧绠$悊</view>
</view>
-
+ <view class="interact-item" @click="navigateTo('/pages/goods-manager/goodsList/goodsList')">
+ <image src="/static/mine/order.png" mode=""></image>
+ <view>鍟嗘埛璁㈠崟绠$悊</view>
+ </view>
</view>
</div>
diff --git a/pages/tabbar/video/video.vue b/pages/tabbar/video/video.vue
index af7dfeb..619c135 100644
--- a/pages/tabbar/video/video.vue
+++ b/pages/tabbar/video/video.vue
@@ -132,7 +132,7 @@
<view class="goods-price" style="flex: 1;">楼{{ goods.price }}</view>
<view @click.stop="() => {}" style="flex: 1;display: flex;justify-content: center;align-items: center;">
<view style="width: 90rpx">鏁伴噺锛�</view>
- <uni-number-box v-model="goods.goodsNum" :min="0"/>
+ <uni-number-box v-model="goods.goodsNum" :min="1"/>
</view>
</view>
</view>
@@ -249,7 +249,6 @@
videoFileKey: '',
videoDuration: 0,
videoFit: 'cover',
- goodsId: '',
videoContentType: 'video',
videoImgs: [],
tags: [],
@@ -543,10 +542,9 @@
// 閫夋嫨鍟嗗搧
chooseGoods() {
if(this.selectedGoodsList.length > 0) {
- const selectedGoodsIds = new Set(this.selectedGoodsList.map(i => i.goodsId));
- console.log(selectedGoodsIds, "mimade");
+ const selectedGoodsSkuIds = new Set(this.selectedGoodsList.map(i => i.id));
this.goodsList?.forEach(goods => {
- this.$set(goods, 'selected', selectedGoodsIds.has(goods.goodsId));
+ this.$set(goods, 'selected', selectedGoodsSkuIds.has(goods.id));
});
}
this.showGoodsPicker = true;
@@ -638,7 +636,7 @@
if (valid && this.canPublish) {
this.loading = true;
this.formData.fileInfo = this.videoInfo;
- this.formData["goodsList"] = this.selectedGoodsList.map(item => {return {goodsId: item.goodsId, goodsNum: item.goodsNum}});
+ this.formData["goodsList"] = this.selectedGoodsList.map(item => {return {goodsId: item.goodsId, goodsSkuId: item.id, goodsNum: item.goodsNum}});
publish(this.formData).then(res => {
uni.showToast({
title: '瑙嗛宸叉彁浜ゅ鏍竳',
@@ -683,7 +681,6 @@
cover: '',
videoFit: 'cover',
videoDuration: 0,
- goodsId: '',
videoContentType: 'video',
videoImgs: [],
tags: [],
diff --git a/pages/video/home-page.vue b/pages/video/home-page.vue
index 5ce3063..4aebb07 100644
--- a/pages/video/home-page.vue
+++ b/pages/video/home-page.vue
@@ -24,47 +24,47 @@
<text class="stat-label">鑾疯禐</text>
</view>
</view>
-
+
<!-- 鍏虫敞鎸夐挳 -->
<view class="follow-btn-container" v-if="!userInfo.self">
- <button
- class="follow-btn"
- :class="{followed: userInfo.hasSub}"
+ <button
+ class="follow-btn"
+ :class="{followed: userInfo.hasSub}"
@click="toggleFollow"
>
{{userInfo.hasSub ? '鍙栨秷鍏虫敞' : '鍏虫敞'}}
</button>
</view>
-
+
<view class="edit-icon" @click="editInfo" v-if="userInfo.self">
<uni-icons type="compose" size="20" color="#666"></uni-icons>缂栬緫涓婚〉淇℃伅
</view>
</view>
-
+
<!-- 浣滃搧/鍠滄鍒囨崲 -->
<view class="tab-bar">
- <view
- class="tab-item"
- :class="{active: currentTab === 'works'}"
+ <view
+ class="tab-item"
+ :class="{active: currentTab === 'works'}"
@click="switchTab('works')"
>
浣滃搧{{`(${videoTotal})`}}
</view>
- <view
- class="tab-item"
- :class="{active: currentTab === 'likes'}"
+ <view
+ class="tab-item"
+ :class="{active: currentTab === 'likes'}"
@click="switchTab('likes')"
>
鍠滄
</view>
</view>
-
+
<!-- 瑙嗛鍒楄〃 -->
<scroll-view class="video-list" scroll-y :show-scrollbar="false" @scrolltolower="getPage" v-show="currentTab === 'works' && videoList.length > 0">
<view class="video-container">
<view
- class="video-item"
- v-for="(item, index) in videoList"
+ class="video-item"
+ v-for="(item, index) in videoList"
:key="item.id"
>
<image class="video-cover" @click="playAuthorVideo(index)" :src="item.videoContentType === 'video' ? item.coverUrl : item.imgs[0]" mode="aspectFill"></image>
@@ -91,8 +91,8 @@
<scroll-view class="video-list" scroll-y :show-scrollbar="false" @scrolltolower="getPage" v-show="currentTab === 'likes' && collectVideoList.length > 0">
<view class="video-container">
<view
- class="video-item"
- v-for="(item, index) in collectVideoList"
+ class="video-item"
+ v-for="(item, index) in collectVideoList"
:key="item.id"
@click="playCollectVideo(index)"
>
@@ -105,10 +105,10 @@
</view>
</view>
</view>
- </view>
+ </view>
</view>
</scroll-view>
-
+
<!-- 绌虹姸鎬� -->
<view class="empty-state" v-if="videoList.length === 0 && currentTab === 'works'">
<!-- <image src="/static/images/empty.png" mode="aspectFit" class="empty-image"></image> -->
@@ -119,13 +119,13 @@
<!-- <image src="/static/images/empty.png" mode="aspectFit" class="empty-image"></image> -->
<text class="empty-text">杩樻病鏈夌偣璧炰綔鍝佸摝~</text>
</view>
-
+
<!-- 鍒犻櫎瑙嗛鎻愰啋妗� -->
<uni-popup ref="delDialog" type="dialog">
<uni-popup-dialog type="error" cancelText="鍙栨秷" confirmText="鍒犻櫎" title="鎻愰啋" :content="`鎮ㄦ鍦ㄥ垹闄わ細${opVideo.title}`" @confirm="deleteVideo"
@close="dialogClose"></uni-popup-dialog>
</uni-popup>
-
+
<!-- 涓嬫灦瑙嗛鎻愰啋妗� -->
<uni-popup ref="downDialog" type="dialog">
<uni-popup-dialog type="error" cancelText="鍙栨秷" confirmText="涓嬫灦" title="鎻愰啋" :content="`鎮ㄦ鍦ㄤ笅鏋讹細${opVideo.title}`" @confirm="downVideo"
@@ -383,14 +383,14 @@
url: `/pages/video/home-page-edit?authorId=${this.authorId}&avatar=${this.userInfo.avatar}&motto=${this.userInfo.motto || ''}&nickName=${this.userInfo.nickName}`
});
},
-
+
// 璺宠浆鍒扮矇涓�/鍏虫敞鍒楄〃
navigateToFollow(type) {
uni.navigateTo({
url: `/pages/user/follow?type=${type}`
});
},
-
+
// 璺宠浆鍒扮偣璧炲垪琛�
navigateToLike() {
uni.navigateTo({
@@ -624,15 +624,15 @@
height: 70rpx;
line-height: 70rpx;
padding: 0 40rpx;
-
+
&::after {
border: none;
}
-
+
&.followed {
background-color: #f5f5f5;
color: #666;
}
}
-</style>
\ No newline at end of file
+</style>
diff --git a/pages/video/video-edit.vue b/pages/video/video-edit.vue
index 1b51fe7..bfa119a 100644
--- a/pages/video/video-edit.vue
+++ b/pages/video/video-edit.vue
@@ -132,7 +132,7 @@
<view class="goods-price" style="flex: 1;">楼{{ goods.price }}</view>
<view @click.stop="() => {}" style="flex: 1;display: flex;justify-content: center;align-items: center;">
<view style="width: 90rpx">鏁伴噺锛�</view>
- <uni-number-box v-model="goods.goodsNum" :min="0"/>
+ <uni-number-box v-model="goods.goodsNum" :min="1"/>
</view>
</view>
</view>
@@ -250,7 +250,6 @@
videoFileKey: '',
videoDuration: 0,
videoFit: 'cover',
- goodsId: '',
videoContentType: 'video',
videoImgs: [],
tags: [],
@@ -306,7 +305,7 @@
getVideoDetail(id).then(res => {
this.videoInfo.cover = res.data.data.coverUrl
this.videoInfo.url = res.data.data.videoUrl
- this.formData.videoImgs = res.data.data.imgs
+ this.formData.videoImgs = res.data.data.videoImgs
this.formData.videoContentType = res.data.data.videoContentType
this.formData.cover = res.data.data.coverFileKey
this.formData.id = res.data.data.id
@@ -316,6 +315,9 @@
this.formData.videoDuration = res.data.data.videoDuration
this.selectedGoodsList = res.data.data.goodsList
this.formData.tags = res.data.data.tags
+ if (this.formData.videoContentType === 'img') {
+ this.videoPreviewImgs = res.data.data.imgs
+ }
this.showUploadProgress = false
console.log("瑙嗛璇︽儏", this.formData);
})
@@ -565,10 +567,9 @@
// 閫夋嫨鍟嗗搧
chooseGoods() {
if(this.selectedGoodsList.length > 0) {
- const selectedGoodsIds = new Set(this.selectedGoodsList.map(i => i.goodsId));
- console.log(selectedGoodsIds, "mimade");
+ const selectedGoodsSkuIds = new Set(this.selectedGoodsList.map(i => i.id));
this.goodsList?.forEach(goods => {
- this.$set(goods, 'selected', selectedGoodsIds.has(goods.goodsId));
+ this.$set(goods, 'selected', selectedGoodsSkuIds.has(goods.id));
});
}
this.showGoodsPicker = true;
@@ -660,7 +661,7 @@
if (valid && this.canPublish) {
this.loading = true;
this.formData.fileInfo = this.videoInfo;
- this.formData["goodsList"] = this.selectedGoodsList.map(item => {return {goodsId: item.goodsId, goodsNum: item.goodsNum}});
+ this.formData["goodsList"] = this.selectedGoodsList.map(item => {return {goodsId: item.goodsId, goodsSkuId: item.id, goodsNum: item.goodsNum}});
updateVideo(this.formData).then(res => {
uni.showToast({
title: '瑙嗛宸叉彁浜ゅ鏍竳',
@@ -673,10 +674,10 @@
this.tagInput = '';
this.recommendedTags = [];
- // TODO 鍏堣烦棣栭〉,鍚庨潰璺虫垜鐨勮棰戦〉闈�
+ // 璺虫垜鐨勮棰戦〉闈�
setTimeout(() => {
- uni.switchTab({
- url: '/pages/tabbar/index/home'
+ uni.navigateBack({
+ delta: 1
});
}, 1500);
})
@@ -705,7 +706,6 @@
cover: '',
videoFit: 'cover',
videoDuration: 0,
- goodsId: '',
videoContentType: 'video',
videoImgs: [],
tags: [],
diff --git a/pages/video/video-goods-detail.vue b/pages/video/video-goods-detail.vue
index 9d06578..a8fc8a1 100644
--- a/pages/video/video-goods-detail.vue
+++ b/pages/video/video-goods-detail.vue
@@ -29,7 +29,7 @@
<script>
import {getGoodsDetail} from "@/api/video.js"
-
+ import { buyBack } from "@/api/trade.js";
import '@/components/uview-components/uview-ui';
export default {
computed: {
@@ -61,7 +61,17 @@
},
// 鐢熸垚璁㈠崟-鏀粯
toPay() {
-
+ const buyList = this.goodsList.map(goods => {
+ return {
+ skuId: goods.id,
+ num: goods.goodsNum
+ }
+ })
+ buyBack(buyList).then(res => {
+ uni.navigateTo({
+ url: "/pages/order/fillorder?way=CART"
+ })
+ })
}
}
}
diff --git a/pages/video/video-play.vue b/pages/video/video-play.vue
index 4cf61c2..e16b6ac 100644
--- a/pages/video/video-play.vue
+++ b/pages/video/video-play.vue
@@ -1,32 +1,43 @@
<template>
<view class="video-container">
+ <!-- 瑙嗛鍔犺浇 -->
+ <zero-loading v-show="videoLoading" type="circle" color="#0ebd57" text=""></zero-loading>
<!-- 瑙嗛鍒楄〃 -->
<swiper
class="video-swiper"
vertical
- circular
:current="currentIndex"
@change="onSwiperChange"
+ :duration="250"
+ easing-function="linear"
>
- <swiper-item v-for="(item, index) in videoList" :key="item.id">
+ <swiper-item
+ v-for="(item, index) in videoList"
+ :key="item.id"
+ @touchstart="handleSwiperStart"
+ @touchmove="handleSwiperMove"
+ @touchend="handleSwiperEnd(item)"
+ >
<view style="width: 100%;height: 100%;" v-if="item.videoContentType === 'video'">
<!-- 鎾斁鎸夐挳锛堜粎褰撹棰戞殏鍋滄椂鏄剧ず锛� -->
<view
class="play-icon"
@click="togglePlay(index)"
- v-if="!currentVideoIsPlaying"
+ v-show="!currentVideoIsPlaying"
>
<image src="/static/video/play.png" style="width: 45px;height: 45px" mode="aspectFit"></image>
</view>
<video
+ v-if="index >= currentIndex - videoLiveOffset && index <= currentIndex + videoLiveOffset"
:id="'video'+index"
:ref="'video'+index"
:src="item.videoUrl"
- :autoplay="currentIndex === index"
+ :autoplay="index === currentIndex"
:controls="false"
:loop="true"
:object-fit="item.objectFit"
:enable-progress-gesture="false"
+ :show-center-play-btn="false"
class="video-item"
@play="onPlay(item.id, index)"
@pause="onPause(index)"
@@ -34,13 +45,13 @@
@click="togglePlay(index)"
@timeupdate="onTimeUpdate($event)"
@loadedmetadata="onLoadedMetadata($event)"
-
+ @waiting="videoWaiting(index)"
></video>
<!-- 鑷畾涔夋帶鍒舵潯 -->
<view
- @touchstart="handleTouchStart"
- @touchmove="handleTouchMove"
- @touchend="handleTouchEnd"
+ @touchstart.stop="handleTouchStart"
+ @touchmove.stop="handleTouchMove"
+ @touchend.stop="handleTouchEnd"
class="container">
<!-- 杩涘害鏉� - 鏁翠釜鍖哄煙鍙嫋鍔� -->
<view class="process-warp" :style="{ opacity: showProcess ? 1 : 0 }">
@@ -291,24 +302,28 @@
startPlayTime: 0 // 杩欎釜瑙嗛浠庝粈涔堟椂鍊欏紑濮嬫挱鏀剧殑
},
currentVideoIsPlaying: true, // 褰撳墠瑙嗛鏄惁姝e湪鎾斁
- isFullScreen: false,
- windowHeight: 0,
currentIndex: 0, // 褰撳墠鎾斁鐨勮棰戠储寮�
- videoList: [
-
- ], // 瑙嗛鍒楄〃鏁版嵁
- videoContexts: [], // 瑙嗛涓婁笅鏂囧璞¢泦鍚�
+ videoLoading: false, // 瑙嗛缂撳啿涓�
+ videoList: [], // 瑙嗛鍒楄〃鏁版嵁
+ videoBufferOffset: 0.1 ,// 瑙嗛棰勫姞杞藉弬鏁�
+ videoLiveOffset: 2, // 淇濈暀褰撳墠瑙嗛鍓嶅悗鍚勫灏戜釜瑙嗛涓婁笅鏂�
+ touchXY: { // 鐩戝惉宸︽粦鍙虫粦
+ startX: 0,
+ endX: 0,
+ startY: 0,
+ endY: 0
+ },
loading: false, // 鏄惁姝e湪鍔犺浇
videoQuery: {
pageNumber: 1,
- pageSize: 6,
+ pageSize: 10,
authorId: '',
videoFrom: ''
}
}
},
onShow() {
- this.loadVideos()
+ // this.loadVideos()
// 濡傛灉瑙嗛鎸変笅鏆傚仠鍚庡垏鎹㈤〉闈㈠啀鍥炲埌椤甸潰鏃讹紝鍙畻鏆傚仠鏃堕棿锛堝洜涓烘殏鍋滄椂闂村拰绂诲紑椤甸潰鏃堕棿鏄噸澶嶇殑锛屽彧绠椾竴涓級
if(this.startHidenTime !== 0 && this.currentVideoIsPlaying) {
const duration = Date.now() - this.startHidenTime
@@ -321,24 +336,28 @@
onUnload() {
uni.removeStorageSync("playInfo");
},
+ onReady() {
+
+ },
onLoad(option) {
const playInfo = uni.getStorageSync("playInfo", playInfo);
if(playInfo) {
+ this.currentIndex = playInfo.playIndex;
this.videoList = playInfo.videoList;
console.log("鎷垮埌鏁版嵁浜�",playInfo);
this.videoQuery.pageNumber = playInfo.pageNumber;
this.videoNoMore = playInfo.nomore;
this.videoQuery.authorId = option.authorId;
this.videoQuery.videoFrom = option.videoFrom;
- this.currentIndex = playInfo.playIndex;
+ this.currentVideoIsPlaying = true;
+ this.$nextTick(() => {
+ const videoContext = uni.createVideoContext(`video${this.currentIndex}`, this);
+ videoContext.play()
+ })
} else {
this.videoQuery.videoFrom = 'recommend';
this.loadVideos();
}
- },
- onReady() {
- // 鍒濆鍖栬棰戜笂涓嬫枃
- this.initVideoContexts();
},
onShareAppMessage(e) {
const userInfo = storage.getUserInfo();
@@ -623,13 +642,6 @@
}
})
},
- // 鍒濆鍖栬棰戜笂涓嬫枃
- initVideoContexts() {
- this.videoContexts = this.videoList.map((_, index) => {
- let videoContent = uni.createVideoContext(`video${index}`, this);
- return videoContent;
- });
- },
// 鍔犺浇瑙嗛鏁版嵁
async loadVideos() {
@@ -647,9 +659,6 @@
),
];
}
- this.$nextTick(() => {
- this.initVideoContexts();
- });
this.loading = false;
if(res.data.data.length < this.videoQuery.pageSize) {
this.videoNoMore = true;
@@ -661,29 +670,75 @@
// 婊戝姩鍒囨崲瑙嗛
onSwiperChange(e) {
- // 濡傛灉瑙嗛澶勪簬鏆傚仠鐘舵�佸線涓嬪埛瑙嗛锛岄偅涔堥渶瑕佸啀璁$畻涓�娆℃殏鍋滄椂闂�
- if(!this.currentVideoIsPlaying) {
- if(this.startPauseTime !== 0) {
- const duration = Date.now() - this.startPauseTime
- this.totalPauseTime += duration
- }
- }
- // 淇濆瓨涓婁竴涓棰戠殑鎾斁璁板綍
- this.savePlayRecord()
- const oldIndex = this.currentIndex;
- this.currentIndex = e.detail.current;
-
- // 鏆傚仠涓婁竴涓棰�
- if (this.videoContexts[oldIndex]) {
- this.videoContexts[oldIndex].pause();
+ this.videoLoading = false
+ // 濡傛灉瑙嗛澶勪簬鏆傚仠鐘舵�佸線涓嬪埛瑙嗛锛岄偅涔堥渶瑕佸啀璁$畻涓�娆℃殏鍋滄椂闂�
+ if(!this.currentVideoIsPlaying) {
+ if(this.startPauseTime !== 0) {
+ const duration = Date.now() - this.startPauseTime
+ this.totalPauseTime += duration
+ }
+ }
+ // 淇濆瓨涓婁竴涓棰戠殑鎾斁璁板綍
+ this.savePlayRecord()
+ const oldIndex = this.currentIndex;
+ this.currentIndex = e.detail.current;
+ const videoContext = uni.createVideoContext(`video${oldIndex}`, this);
+ // 鏆傚仠涓婁竴涓棰�
+ videoContext.pause();
+ this.startPauseTime = 0;
+
+ // 璁剧疆褰撳墠鎾斁瑙嗛鐨勬�绘椂闀�
+ this.duration = this.videoList[this.currentIndex].videoDuration;
+ this.formartDuration = this.sliderFormatTime(this.duration);
+
+ // 鎾斁褰撳墠瑙嗛
+ const videoContext1 = uni.createVideoContext(`video${this.currentIndex}`, this);
+ videoContext1.play()
+ // 濡傛灉鍓╀綑瑙嗛涓嶈冻锛岃Е鍙戣姹傝幏鍙栨洿澶氳棰�
+ if (this.videoList.length - 1 < this.currentIndex + this.videoLiveOffset) {
+ this.loadVideos()
+ }
+ },
+
+ // 寮�濮嬭Е鎽�
+ handleSwiperStart(e) {
+ this.touchXY.startX = e.touches[0].pageX
+ this.touchXY.startY = e.touches[0].pageY
+ },
+ // 瑙︽懜涓�
+ handleSwiperMove(e) {
+ this.touchXY.endX = e.touches[0].pageX
+ this.touchXY.endY = e.touches[0].pageY
+ },
+ // 缁撴潫瑙︽懜
+ handleSwiperEnd(item) {
+ // 闃叉婊戝姩婊氬姩鏉′篃瑙﹀彂璺宠浆
+ if (this.showProcess) {
+ return
}
- this.startPauseTime = 0;
- // 鎾斁褰撳墠瑙嗛
- if (this.videoContexts[this.currentIndex]) {
- this.videoContexts[this.currentIndex].play();
+ const diffX = this.touchXY.endX - this.touchXY.startX
+ const diffY = this.touchXY.endY - this.touchXY.startY
+
+ // 鍒ゆ柇鏄惁鏄í鍚戞粦鍔紙X杞村彉鍖栧ぇ浜嶻杞村彉鍖栵級
+ if (Math.abs(diffX) > Math.abs(diffY)) {
+ if (diffX > 0) {
+ console.log('鍙虫粦')
+ if (item.goodsList && item.goodsList.length > 0) {
+ this.jumpToPay(item.id)
+ }
+ } else {
+ console.log('宸︽粦')
+ }
+ }
+ // 閲嶇疆鍧愭爣
+ this.touchXY = {
+ startX: 0,
+ endX: 0,
+ startY: 0,
+ endY: 0
}
- },
+ },
// 鑾峰彇杩涘害鏉$殑浣嶇疆鍜屽昂瀵�
getBarRect() {
@@ -703,7 +758,8 @@
this.startProgress = this.progress; // 璁板綍寮�濮嬫椂鐨勮繘搴�
this.startX = e.touches[0].pageX;
console.log("璁板綍寮�濮嬫椂鐨勮繘搴�", this.startProgress);
- this.videoContexts[this.currentIndex].pause()
+ const videoContext = uni.createVideoContext(`video${this.currentIndex}`, this);
+ videoContext.pause()
// this.updateProgress(e);
},
@@ -711,7 +767,6 @@
handleTouchMove(e) {
if (!this.isDragging || !this.barWidth) return;
clearTimeout(this.processHidenTimer)
- this.videoContexts[this.currentIndex].pause()
this.updateProgress(e);
},
@@ -719,11 +774,12 @@
handleTouchEnd() {
this.isDragging = false;
console.log("婊戝姩缁撴潫", this.duration * this.progress);
- this.videoContexts[this.currentIndex].seek(this.duration * this.progress / 100)
- this.videoContexts[this.currentIndex].play()
+ const videoContext = uni.createVideoContext(`video${this.currentIndex}`, this);
+ videoContext.seek(this.duration * this.progress / 100)
+ videoContext.play()
this.processHidenTimer = setTimeout(() => {
- this.showProcess = false;
- }, 1000);
+ this.showProcess = false;
+ }, 1000);
},
// 鏇存柊杩涘害
@@ -736,7 +792,6 @@
// 灏嗗儚绱犺窛绂昏浆鎹负杩涘害澧為噺
const deltaProgress = (deltaX / this.barWidth) * 100;
- console.log("杩涘害澧為噺", deltaProgress);
// 璁$畻鏂拌繘搴� = 寮�濮嬫椂鐨勮繘搴� + 婊戝姩澧為噺
let newProgress = this.startProgress + deltaProgress;
@@ -770,16 +825,16 @@
},
// 鍗曞嚮灞忓箷锛氭殏鍋滄垨缁х画鎾斁
togglePlay(index) {
+ console.log("鍗曞嚮瑙嗛", index);
+ const videoContext = uni.createVideoContext(`video${index}`, this);
if(this.currentVideoIsPlaying) {
- this.videoContexts[index].pause();
+ videoContext.pause();
} else {
- this.videoContexts[index].play();
+ videoContext.play();
}
},
// 瑙嗛鎾斁浜嬩欢
onPlay(id, index) {
- this.getBarRect()
- this.progress = 0
if(index === this.currentIndex) {
this.currentVideoIsPlaying = true;
if(! this.duration) {
@@ -788,9 +843,11 @@
this.formartDuration = this.sliderFormatTime(this.duration);
}
} else {
- this.currentVideoIsPlaying = false;
return
}
+ this.getBarRect()
+ this.progress = 0
+ console.log(id, index, "瑙﹀彂鎾斁");
this.playRecord.videoId = id;
// 娌″垵濮嬪寲鎵嶈祴鍊硷紝鍥犱负涓�涓棰戦噸澶嶆挱鏀緊nPlay浼氶噸澶嶈Е鍙�
if(this.playRecord.startPlayTime === 0) {
@@ -800,6 +857,7 @@
const duration = Date.now() - this.startPauseTime
this.totalPauseTime += duration
}
+ this.videoLoading = false
},
// 瑙嗛鏆傚仠浜嬩欢
@@ -807,11 +865,8 @@
console.log(index, "瑙﹀彂鏆傚仠");
if(index === this.currentIndex) {
this.currentVideoIsPlaying = false;
- } else {
- this.currentVideoIsPlaying = true;
- return
+ this.startPauseTime = Date.now()
}
- this.startPauseTime = Date.now()
},
// 瑙嗛缁撴潫浜嬩欢
@@ -821,9 +876,17 @@
// 璁板綍鎾斁鏃堕暱
onTimeUpdate(e) {
+ this.videoLoading = false
this.playRecord.playAt = e.detail.currentTime
this.currentTime = e.detail.currentTime;
this.progress = (e.detail.currentTime / this.duration) * 100
+ },
+ // 瑙嗛缂撳啿
+ videoWaiting(index) {
+ if (index === this.currentIndex) {
+ console.log("瑙嗛缂撳啿涓�傘�傘��");
+ this.videoLoading = true;
+ }
},
// 鑾峰彇瑙嗛鎬绘椂闀�
onLoadedMetadata(e) {
@@ -872,7 +935,7 @@
.video-item {
width: 100%;
height: 100%;
- object-fit: cover;
+ /* object-fit: cover; */
}
.play-icon {
position: absolute;
diff --git a/static/mine/order.png b/static/mine/order.png
new file mode 100644
index 0000000..8b3ad56
--- /dev/null
+++ b/static/mine/order.png
Binary files differ
diff --git a/uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue b/uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue
index 4d0deef..5608140 100644
--- a/uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue
+++ b/uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue
@@ -154,6 +154,7 @@
}
.custom-style{
border-radius: 0 24rpx 24rpx 0;
+ top: 100px;
}
.uni-drawer--left {
diff --git a/uni_modules/zero-loading/changelog.md b/uni_modules/zero-loading/changelog.md
new file mode 100644
index 0000000..af6947d
--- /dev/null
+++ b/uni_modules/zero-loading/changelog.md
@@ -0,0 +1,51 @@
+## 1.4.2锛�2025-04-03锛�
+## 澧炲姞涓や釜鍔ㄧ敾
+| locating | 瀹氫綅 (鑷畾涔夐鑹�) |
+| photo | 鐓х墖 (鑷畾涔夐鑹�) |
+## 1.4.1锛�2024-07-02锛�
+### 1. 澧炲姞鍔ㄧ敾equal(绛夎竟), wobble(鎽囨憜)
+### 2. 鍘熸潵鐨則riangle(涓夎)鏀逛负surround(鐜粫)
+### 3. 鏂板鍙嚜瀹氫箟棰滆壊椤�
+## 1.4.0锛�2024-06-28锛�
+
+## 澧炲姞 loading 鍔犺浇鏂囧瓧鎻愰啋閰嶇疆椤�,榛樿 false
+
+## 1.3.2锛�2023-10-31锛�
+
+淇敼閬僵榛樿閫忔槑搴︿负 0.1
+
+## 1.3.1锛�2023-10-31锛�
+
+## 鏂板鏀寔,鑷畾涔夊姩鐢婚鑹�(浠呴儴鍒嗗姩鐢绘敮鎸�)
+
+## 鏂板鍔ㄧ敾-annulus(鍦嗙幆)
+
+## 1.3.0锛�2023-08-11锛�
+
+鏀寔 vue3 浣跨敤, 澧炲姞鍔ㄧ敾绫诲瀷 radar(闆疯揪)
+
+## 1.2.2锛�2023-06-12锛�
+
+澧炲姞 maskOpacity, maskMini, maskDark 鑷畾涔夊弬鏁�, 鎻愪緵鏇翠赴瀵岀殑鑷畾涔夐伄缃╁眰鑳藉姏
+
+## 1.2.1锛�2022-09-09锛�
+
+澧炲姞榻胯疆鍔ㄧ敾 type=gear
+
+## 1.2.0锛�2022-05-27锛�
+
+1. 澧炲姞鍔犺浇绫诲瀷-鍓戞皵锛坰word锛夛紝鍘熷瓙锛坅tom锛�
+2. 榛樿绫诲瀷鏀逛负 atom
+3. 閬僵閫忔槑搴﹁皟鏁�
+
+## 1.1.1锛�2022-04-02锛�
+
+鏇存柊浣跨敤璇存槑
+
+## 1.1.0锛�2022-02-23锛�
+
+澧炲姞 type="love" 鐨勫績褰㈠姞杞藉姩鐢�
+
+## 1.0.0锛�2022-01-28锛�
+
+棣栨鍙戝竷
diff --git a/uni_modules/zero-loading/components/zero-loading/static/loading-annulus.vue b/uni_modules/zero-loading/components/zero-loading/static/loading-annulus.vue
new file mode 100644
index 0000000..260301f
--- /dev/null
+++ b/uni_modules/zero-loading/components/zero-loading/static/loading-annulus.vue
@@ -0,0 +1,45 @@
+<template>
+ <view class="animations">
+ <view class="loader" :style="{ '--color': color }"></view>
+ </view>
+</template>
+
+<script>
+export default {
+ name: "loading-annulus",
+ props: {
+ color: {
+ type: String,
+ default: "#0396FF",
+ },
+ },
+ data() {
+ return {};
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+.loader {
+ width: 60px;
+ height: 60px;
+}
+
+.loader::before {
+ content: "";
+ box-sizing: border-box;
+ position: absolute;
+ width: 60px;
+ height: 60px;
+ border-radius: 50%;
+ border-top: 2px solid var(--color);
+ border-right: 2px solid transparent;
+ animation: spinner 1s linear infinite;
+}
+
+@keyframes spinner {
+ to {
+ transform: rotate(360deg);
+ }
+}
+</style>
diff --git a/uni_modules/zero-loading/components/zero-loading/static/loading-atom.vue b/uni_modules/zero-loading/components/zero-loading/static/loading-atom.vue
new file mode 100644
index 0000000..3b3b75e
--- /dev/null
+++ b/uni_modules/zero-loading/components/zero-loading/static/loading-atom.vue
@@ -0,0 +1,108 @@
+<template>
+ <view class="animations">
+ <view class="box" :style="{ '--color': color }">
+ <view class="atom"></view>
+ <view class="atom"></view>
+ <view class="atom"></view>
+ <view class="dot"></view>
+ </view>
+ </view>
+</template>
+
+<script>
+export default {
+ name: "loading-atom",
+ props: {
+ color: {
+ type: String,
+ default: "#0396FF",
+ },
+ },
+ data() {
+ return {};
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+.box {
+ position: relative;
+ width: 120rpx;
+ height: 120rpx;
+}
+.dot {
+ position: absolute;
+ width: 10px;
+ height: 10px;
+ border-radius: 50%;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ background: var(--color);
+ animation: dotbreath 2s linear infinite;
+}
+.atom {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ border-radius: 50%;
+ border-left-width: 6rpx;
+ border-top-width: 6rpx;
+ border-left-color: var(--color);
+ border-left-style: solid;
+ border-top-style: solid;
+ border-top-color: transparent;
+}
+.atom:nth-of-type(1) {
+ left: 0%;
+ top: 0%;
+ animation: atom1 1s linear infinite;
+}
+.atom:nth-of-type(2) {
+ right: 0%;
+ top: 0%;
+ animation: atom2 1s linear infinite;
+}
+.atom:nth-of-type(3) {
+ right: 0%;
+ bottom: 0%;
+ animation: atom3 1s linear infinite;
+}
+@keyframes dotbreath {
+ 0% {
+ opacity: 1;
+ }
+
+ 50% {
+ opacity: 0.5;
+ }
+ 100% {
+ opacity: 1;
+ }
+}
+@keyframes atom1 {
+ 0% {
+ transform: rotateZ(120deg) rotateX(66deg) rotateZ(0deg);
+ }
+ 100% {
+ transform: rotateZ(120deg) rotateX(66deg) rotateZ(360deg);
+ }
+}
+@keyframes atom2 {
+ 0% {
+ transform: rotateZ(240deg) rotateX(66deg) rotateZ(0deg);
+ }
+ 100% {
+ transform: rotateZ(240deg) rotateX(66deg) rotateZ(360deg);
+ }
+}
+
+@keyframes atom3 {
+ 0% {
+ transform: rotateZ(360deg) rotateX(66deg) rotateZ(0deg);
+ }
+ 100% {
+ transform: rotateZ(360deg) rotateX(66deg) rotateZ(360deg);
+ }
+}
+</style>
diff --git a/uni_modules/zero-loading/components/zero-loading/static/loading-bounce.vue b/uni_modules/zero-loading/components/zero-loading/static/loading-bounce.vue
new file mode 100644
index 0000000..860d23d
--- /dev/null
+++ b/uni_modules/zero-loading/components/zero-loading/static/loading-bounce.vue
@@ -0,0 +1,84 @@
+<template>
+ <view class="animations">
+ <view class="box">
+ <view class="dot dot1"></view>
+ <view class="dot dot2"></view>
+ <view class="dot dot3"></view>
+ </view>
+ </view>
+</template>
+
+<script>
+export default {
+ name: "loading-bounce",
+ data() {
+ return {};
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+.box {
+ width: 100rpx;
+ height: 50rpx;
+ position: relative;
+}
+.dot {
+ width: 14rpx;
+ height: 14rpx;
+ background: #007aff;
+ border-radius: 50%;
+ position: absolute;
+ top: calc(50% - 5rpx);
+}
+
+.dot1 {
+ background: #1fa2ff;
+ left: 0rpx;
+ -webkit-animation: bounce 0.5s cubic-bezier(0.77, 0.47, 0.64, 0.28) alternate
+ infinite;
+ animation: bounce 0.5s cubic-bezier(0.77, 0.47, 0.64, 0.28) alternate infinite;
+}
+
+.dot2 {
+ background: #12d8fa;
+ left: 40rpx;
+ -webkit-animation: bounce 0.5s 0.2s cubic-bezier(0.77, 0.47, 0.64, 0.28)
+ alternate infinite;
+ animation: bounce 0.5s 0.2s cubic-bezier(0.77, 0.47, 0.64, 0.28) alternate
+ infinite;
+}
+
+.dot3 {
+ background: #29ffc6;
+ left: 80rpx;
+ -webkit-animation: bounce 0.5s 0.4s cubic-bezier(0.77, 0.47, 0.64, 0.28)
+ alternate infinite;
+ animation: bounce 0.5s 0.4s cubic-bezier(0.77, 0.47, 0.64, 0.28) alternate
+ infinite;
+}
+
+@-webkit-keyframes bounce {
+ 0% {
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ }
+
+ 100% {
+ -webkit-transform: translateY(-20rpx);
+ transform: translateY(-20rpx);
+ }
+}
+
+@keyframes bounce {
+ 0% {
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ }
+
+ 100% {
+ -webkit-transform: translateY(-20rpx);
+ transform: translateY(-20rpx);
+ }
+}
+</style>
diff --git a/uni_modules/zero-loading/components/zero-loading/static/loading-circle.vue b/uni_modules/zero-loading/components/zero-loading/static/loading-circle.vue
new file mode 100644
index 0000000..958bb14
--- /dev/null
+++ b/uni_modules/zero-loading/components/zero-loading/static/loading-circle.vue
@@ -0,0 +1,96 @@
+<template>
+ <view class="animations">
+ <view class="loader" :style="{ '--color': color }"></view>
+ </view>
+</template>
+
+<script>
+export default {
+ name: "loading-circle",
+ props: {
+ color: {
+ type: String,
+ default: "#0396FF",
+ },
+ },
+ data() {
+ return {};
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+// .container {
+// position: absolute;
+// top: 50%;
+// left: 50%;
+// transform: translate(-50%, -50%);
+// }
+.loader {
+ display: block;
+ width: 120rpx;
+ height: 120rpx;
+ border-radius: 50%;
+ border: 3rpx solid transparent;
+ border-top-color: var(--color);
+ -webkit-animation: spin 2s linear infinite;
+ animation: spin 2s linear infinite;
+ position: relative;
+}
+
+.loader::before {
+ content: "";
+ position: absolute;
+ top: 8rpx;
+ left: 8rpx;
+ right: 8rpx;
+ bottom: 8rpx;
+ border-radius: 50%;
+ border: 3rpx solid transparent;
+ border-top-color: var(--color);
+ -webkit-animation: spin 3s linear infinite;
+ animation: spin 3s linear infinite;
+}
+
+.loader::after {
+ content: "";
+ position: absolute;
+ top: 16rpx;
+ left: 16rpx;
+ right: 16rpx;
+ bottom: 16rpx;
+ border-radius: 50%;
+ border: 3rpx solid transparent;
+ border-top-color: var(--color);
+ -webkit-animation: spin 1.5s linear infinite;
+ animation: spin 1.5s linear infinite;
+}
+
+@-webkit-keyframes spin {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ -ms-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ -webkit-transform: rotate(360deg);
+ -ms-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+}
+
+@keyframes spin {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ -ms-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ -webkit-transform: rotate(360deg);
+ -ms-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+}
+</style>
diff --git a/uni_modules/zero-loading/components/zero-loading/static/loading-equal.vue b/uni_modules/zero-loading/components/zero-loading/static/loading-equal.vue
new file mode 100644
index 0000000..b68b86c
--- /dev/null
+++ b/uni_modules/zero-loading/components/zero-loading/static/loading-equal.vue
@@ -0,0 +1,81 @@
+<template>
+ <view class="animations">
+ <view class="loader" :style="{ '--color': color }"></view>
+ </view>
+</template>
+
+<script>
+export default {
+ name: "loading-equal",
+ props: {
+ color: {
+ type: String,
+ default: "#ff1919",
+ },
+ },
+ data() {
+ return {};
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+.loader {
+ width: 50px;
+ aspect-ratio: 1.154;
+ position: relative;
+ background: conic-gradient(
+ from 120deg at 50% 64%,
+ #0000,
+ var(--color) 1deg 120deg,
+ #0000 121deg
+ );
+ animation: spin 1.5s infinite cubic-bezier(0.3, 1, 0, 1);
+}
+
+.loader:before,
+.loader:after {
+ content: "";
+ position: absolute;
+ inset: 0;
+ background: inherit;
+ transform-origin: 50% 66%;
+ animation: separate 1.5s infinite;
+}
+
+.loader:after {
+ --s: -1;
+}
+
+@keyframes spin {
+ 0%,
+ 30% {
+ transform: rotate(0);
+ }
+
+ 70% {
+ transform: rotate(120deg);
+ }
+
+ 70.01%,
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+@keyframes separate {
+ 0% {
+ transform: rotate(calc(var(--s, 1) * 120deg)) translate(0);
+ }
+
+ 30%,
+ 70% {
+ transform: rotate(calc(var(--s, 1) * 120deg))
+ translate(calc(var(--s, 1) * -5px), 10px);
+ }
+
+ 100% {
+ transform: rotate(calc(var(--s, 1) * 120deg)) translate(0);
+ }
+}
+</style>
diff --git a/uni_modules/zero-loading/components/zero-loading/static/loading-eyes.vue b/uni_modules/zero-loading/components/zero-loading/static/loading-eyes.vue
new file mode 100644
index 0000000..f7a18d1
--- /dev/null
+++ b/uni_modules/zero-loading/components/zero-loading/static/loading-eyes.vue
@@ -0,0 +1,78 @@
+<template>
+ <view class="animations">
+ <view class="box">
+ <view class="eye"></view>
+ <view class="eye"></view>
+ </view>
+ </view>
+</template>
+
+<script>
+export default {
+ name: "loading-eyes",
+ data() {
+ return {};
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+.box {
+ width: 110rpx;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.eye {
+ width: 50rpx;
+ height: 50rpx;
+ background: linear-gradient(135deg, #1fa2ff, #12d8fa);
+ border-radius: 50%;
+ position: relative;
+}
+
+.eye:after {
+ background-color: #ffffff;
+ width: 18rpx;
+ height: 18rpx;
+ border-radius: 50%;
+ left: 20rpx;
+ top: 24rpx;
+ position: absolute;
+ content: "";
+ -webkit-animation: eyeball 1s linear infinite alternate;
+ -moz-animation: eyeball 1s linear infinite alternate;
+ animation: eyeball 1s linear infinite alternate;
+}
+
+@-webkit-keyframes eyeball {
+ 0% {
+ left: 30rpx;
+ }
+
+ 100% {
+ left: 2rpx;
+ }
+}
+
+@-moz-keyframes eyeball {
+ 0% {
+ left: 30rpx;
+ }
+
+ 100% {
+ left: 2rpx;
+ }
+}
+
+@keyframes eyeball {
+ 0% {
+ left: 30rpx;
+ }
+
+ 100% {
+ left: 2rpx;
+ }
+}
+</style>
diff --git a/uni_modules/zero-loading/components/zero-loading/static/loading-gear.vue b/uni_modules/zero-loading/components/zero-loading/static/loading-gear.vue
new file mode 100644
index 0000000..19ce873
--- /dev/null
+++ b/uni_modules/zero-loading/components/zero-loading/static/loading-gear.vue
@@ -0,0 +1,118 @@
+<template>
+ <view class="animations">
+ <view class="box">
+ <view class="gear1">
+ <view class="inner inner1"> </view>
+ <view class="inner inner2"> </view>
+ <view class="inner inner3"> </view>
+ </view>
+ <view class="gear2">
+ <view class="inner inner1"> </view>
+ <view class="inner inner2"> </view>
+ <view class="inner inner3"> </view>
+ </view>
+ <view class="gear3">
+ <view class="inner inner1"> </view>
+ <view class="inner inner2"> </view>
+ <view class="inner inner3"> </view>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+export default {
+ name: "loading-gear",
+ data() {
+ return {};
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+$size: 80rpx;
+$bgc: red;
+
+.box {
+ width: 200rpx;
+ height: 200rpx;
+ position: relative;
+}
+
+@mixin gear($size: $size, $bgc: $bgc) {
+ width: $size;
+ height: $size;
+ .inner {
+ position: absolute;
+ width: $size;
+ height: $size;
+ top: 0;
+ left: 0;
+ background: $bgc;
+ border-radius: 6rpx;
+ mask: radial-gradient(transparent 40%, #fff 60%);
+ }
+
+ .inner2 {
+ transform: rotate(120deg);
+ }
+
+ .inner3 {
+ transform: rotate(240deg);
+ }
+
+ // &:after {
+ // position: absolute;
+ // content: '';
+ // background: #fff;
+ // width: $size / 1.8;
+ // height: $size / 1.8;
+ // border-radius: 100%;
+ // top: 50%;
+ // left: 50%;
+ // transform: translate(-50%, -50%);
+ // }
+}
+
+.gear1 {
+ @include gear(60rpx, #0396ff);
+ position: absolute;
+ top: 35rpx;
+ left: 35rpx;
+ animation: rotate 5s infinite linear;
+}
+
+.gear2 {
+ @include gear(50rpx, #dd524d);
+ position: absolute;
+ top: 50rpx;
+ left: 110rpx;
+ animation: rotateR 5s infinite linear;
+}
+.gear3 {
+ @include gear(50rpx, #f0ad4e);
+ position: absolute;
+ top: 110rpx;
+ left: 50rpx;
+ animation: rotateR 5s infinite linear;
+}
+
+@keyframes rotate {
+ from {
+ transform: rotate(0deg);
+ }
+
+ to {
+ transform: rotate(360deg);
+ }
+}
+@keyframes rotateR {
+ from {
+ transform: rotate(0deg);
+ }
+
+ to {
+ transform: rotate(-360deg);
+ }
+}
+</style>
diff --git a/uni_modules/zero-loading/components/zero-loading/static/loading-locating.vue b/uni_modules/zero-loading/components/zero-loading/static/loading-locating.vue
new file mode 100644
index 0000000..7e140ec
--- /dev/null
+++ b/uni_modules/zero-loading/components/zero-loading/static/loading-locating.vue
@@ -0,0 +1,81 @@
+<template>
+ <view class="animations">
+ <view class="loader" :style="{ '--color': color }"></view>
+ </view>
+ </template>
+
+ <script>
+ export default {
+ name: "loading-locating",
+ props: {
+ color: {
+ type: String,
+ default: "#0396FF",
+ },
+ },
+ data() {
+ return {};
+ },
+ };
+ </script>
+
+ <style lang="scss" scoped>
+
+ .loader {
+ width: 96rpx;
+ height: 96rpx;
+ display: block;
+ margin: 40rpx auto;
+ box-sizing: border-box;
+ position: relative;
+ }
+
+ .loader::after {
+ content: '';
+ width: 96rpx;
+ height: 96rpx;
+ left: 0;
+ bottom: 0;
+ position: absolute;
+ border-radius: 50% 50% 0;
+ border: 30rpx solid var(--color);
+ transform: rotate(45deg) translate(0, 0);
+ box-sizing: border-box;
+ animation: animMarker 0.4s ease-in-out infinite alternate;
+ }
+
+ .loader::before {
+ content: '';
+ box-sizing: border-box;
+ position: absolute;
+ left: 0;
+ right: 0;
+ margin: auto;
+ top: 150%;
+ width: 48rpx;
+ height: 8rpx;
+ border-radius: 50%;
+ background: rgba(0, 0, 0, 0.2);
+ animation: animShadow 0.4s ease-in-out infinite alternate;
+ }
+
+ @keyframes animMarker {
+ 0% {
+ transform: rotate(45deg) translate(10rpx, 10rpx);
+ }
+
+ 100% {
+ transform: rotate(45deg) translate(-10rpx, -10rpx);
+ }
+ }
+
+ @keyframes animShadow {
+ 0% {
+ transform: scale(0.5);
+ }
+
+ 100% {
+ transform: scale(1);
+ }
+ }
+</style>
\ No newline at end of file
diff --git a/uni_modules/zero-loading/components/zero-loading/static/loading-love.vue b/uni_modules/zero-loading/components/zero-loading/static/loading-love.vue
new file mode 100644
index 0000000..9b5e6cd
--- /dev/null
+++ b/uni_modules/zero-loading/components/zero-loading/static/loading-love.vue
@@ -0,0 +1,201 @@
+<template>
+ <view class="animations">
+ <view class="box">
+ <view class="item"></view>
+ <view class="item"></view>
+ <view class="item"></view>
+ <view class="item"></view>
+ <view class="item"></view>
+ <view class="item"></view>
+ <view class="item"></view>
+ <view class="item"></view>
+ <view class="item"></view>
+ </view>
+ </view>
+</template>
+
+<script>
+export default {
+ name: "loading-love",
+ data() {
+ return {};
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+.box {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-flow: row nowrap;
+ height: 160rpx;
+}
+
+.item {
+ background: linear-gradient(to bottom, #f00000, #e73827);
+ width: 16rpx;
+ height: 16rpx;
+ border-radius: 20rpx;
+ margin-right: 10rpx;
+}
+
+.item:nth-child(1) {
+ animation: love1 4s infinite;
+}
+
+.item:nth-child(2) {
+ animation: love2 4s infinite;
+ animation-delay: 0.15s;
+}
+
+.item:nth-child(3) {
+ animation: love3 4s infinite;
+ animation-delay: 0.3s;
+}
+
+.item:nth-child(4) {
+ animation: love4 4s infinite;
+ animation-delay: 0.45s;
+}
+
+.item:nth-child(5) {
+ animation: love5 4s infinite;
+ animation-delay: 0.6s;
+}
+
+.item:nth-child(6) {
+ animation: love4 4s infinite;
+ animation-delay: 0.75s;
+}
+
+.item:nth-child(7) {
+ animation: love3 4s infinite;
+ animation-delay: 0.9s;
+}
+
+.item:nth-child(8) {
+ animation: love2 4s infinite;
+ animation-delay: 1.05s;
+}
+
+.item:nth-child(9) {
+ animation: love1 4s infinite;
+ animation-delay: 1.2s;
+}
+
+@keyframes love1 {
+ 30%,
+ 50% {
+ height: 50rpx;
+ transform: translateY(-20rpx);
+ }
+
+ 75%,
+ 100% {
+ height: 20rpx;
+ transform: translateY(0);
+ }
+}
+
+@keyframes love2 {
+ 30%,
+ 50% {
+ height: 90rpx;
+ transform: translateY(-25rpx);
+ }
+
+ 75%,
+ 100% {
+ height: 20rpx;
+ transform: translateY(0);
+ }
+}
+
+@keyframes love3 {
+ 30%,
+ 50% {
+ height: 120rpx;
+ transform: translateY(-20rpx);
+ }
+
+ 75%,
+ 100% {
+ height: 20rpx;
+ transform: translateY(0);
+ }
+}
+
+@keyframes love4 {
+ 30%,
+ 50% {
+ height: 130rpx;
+ transform: translateY(-10rpx);
+ }
+
+ 75%,
+ 100% {
+ height: 20rpx;
+ transform: translateY(0);
+ }
+}
+
+@keyframes love5 {
+ 30%,
+ 50% {
+ height: 130rpx;
+ transform: translateY(10rpx);
+ }
+
+ 75%,
+ 100% {
+ height: 20rpx;
+ transform: translateY(0);
+ }
+}
+
+// .item:nth-child(1) {
+// height: 50rpx;
+// transform: translateY(-20rpx);
+// }
+
+// .item:nth-child(2) {
+// height: 90rpx;
+// transform: translateY(-25rpx);
+// }
+
+// .item:nth-child(3) {
+// height: 120rpx;
+// transform: translateY(-20rpx);
+// }
+
+// .item:nth-child(4) {
+// height: 130rpx;
+// transform: translateY(-10rpx);
+// }
+
+// .item:nth-child(5) {
+// height: 130rpx;
+// transform: translateY(10rpx);
+// }
+
+// .item:nth-child(6) {
+// height: 130rpx;
+// transform: translateY(-10rpx);
+// }
+
+// .item:nth-child(7) {
+// height: 120rpx;
+// transform: translateY(-20rpx);
+// }
+
+// .item:nth-child(8) {
+// height: 90rpx;
+// transform: translateY(-25rpx);
+// }
+
+// .item:nth-child(9) {
+// height: 50rpx;
+// transform: translateY(-20rpx);
+// }
+</style>
diff --git a/uni_modules/zero-loading/components/zero-loading/static/loading-photo.vue b/uni_modules/zero-loading/components/zero-loading/static/loading-photo.vue
new file mode 100644
index 0000000..3c9b383
--- /dev/null
+++ b/uni_modules/zero-loading/components/zero-loading/static/loading-photo.vue
@@ -0,0 +1,87 @@
+<template>
+ <view class="animations">
+ <view class="loader" :style="{ '--color': color }"></view>
+ </view>
+</template>
+
+<script>
+export default {
+ name: "loading-photo",
+ props: {
+ color: {
+ type: String,
+ default: "#0396FF",
+ },
+ },
+ data() {
+ return {};
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+
+.loader {
+ width: 128rpx;
+ height: 128rpx;
+ position: relative;
+ background: #f4f4f4;
+ border-radius: 8rpx;
+ overflow: hidden;
+}
+
+.loader:before {
+ content: "";
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ width: 80rpx;
+ height: 80rpx;
+ transform: rotate(45deg) translate(30%, 40%);
+ background: var(--color);
+ box-shadow: 64rpx -68rpx 0 10rpx var(--color);
+ animation: slide 2s infinite ease-in-out alternate;
+}
+
+.loader:after {
+ content: "";
+ position: absolute;
+ left: 20rpx;
+ top: 20rpx;
+ width: 28rpx;
+ height: 28rpx;
+ border-radius: 50%;
+ background: var(--color);
+ transform: rotate(0deg);
+ transform-origin: 70rpx 290rpx;
+ animation: rotate 2s infinite ease-in-out;
+}
+
+@keyframes slide {
+ 0% , 100% {
+ bottom: -70rpx
+ }
+
+ 25% , 75% {
+ bottom: -4rpx
+ }
+
+ 20% , 80% {
+ bottom: 4rpx
+ }
+}
+
+@keyframes rotate {
+ 0% {
+ transform: rotate(-15deg)
+ }
+
+ 25% , 75% {
+ transform: rotate(0deg)
+ }
+
+ 100% {
+ transform: rotate(25deg)
+ }
+}
+</style>
diff --git a/uni_modules/zero-loading/components/zero-loading/static/loading-pulse.vue b/uni_modules/zero-loading/components/zero-loading/static/loading-pulse.vue
new file mode 100644
index 0000000..9c32c7e
--- /dev/null
+++ b/uni_modules/zero-loading/components/zero-loading/static/loading-pulse.vue
@@ -0,0 +1,67 @@
+<template>
+ <view class="animations">
+ <view class="box" :style="{ '--color': color }">
+ <view class="pulse-bubble pulse-bubble-1"></view>
+ <view class="pulse-bubble pulse-bubble-2"></view>
+ <view class="pulse-bubble pulse-bubble-3"></view>
+ </view>
+ </view>
+</template>
+
+<script>
+export default {
+ name: "loading-pulse",
+ props: {
+ color: {
+ type: String,
+ default: "#0396FF",
+ },
+ },
+ data() {
+ return {};
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+.box {
+ width: 100rpx;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.pulse-bubble {
+ width: 16rpx;
+ height: 16rpx;
+ border-radius: 50%;
+ background: var(--color);
+}
+
+.pulse-bubble-1 {
+ // background: #1fa2ff;
+ animation: pulse 0.4s ease 0s infinite alternate;
+}
+
+.pulse-bubble-2 {
+ // background: #12d8fa;
+ animation: pulse 0.4s ease 0.2s infinite alternate;
+}
+
+.pulse-bubble-3 {
+ // background: #29ffc6;
+ animation: pulse 0.4s ease 0.4s infinite alternate;
+}
+
+@keyframes pulse {
+ from {
+ opacity: 1;
+ transform: scale(1);
+ }
+
+ to {
+ opacity: 0.25;
+ transform: scale(0.75);
+ }
+}
+</style>
diff --git a/uni_modules/zero-loading/components/zero-loading/static/loading-radar.vue b/uni_modules/zero-loading/components/zero-loading/static/loading-radar.vue
new file mode 100644
index 0000000..ebafa85
--- /dev/null
+++ b/uni_modules/zero-loading/components/zero-loading/static/loading-radar.vue
@@ -0,0 +1,132 @@
+<template>
+ <view class="animations">
+ <view class="radar">
+ <view class="dot dot-1"></view>
+ <view class="dot dot-2"></view>
+ <view class="dot dot-3"></view>
+ <view class="cover"></view>
+ </view>
+ </view>
+</template>
+
+<script>
+export default {
+ name: "loading-radar",
+ data() {
+ return {};
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+$size: 180rpx;
+$dotSize: 4rpx;
+$maincolor: #2da3f6;
+
+.radar {
+ position: relative;
+ z-index: 1;
+ height: $size;
+ width: $size;
+ background: -webkit-repeating-radial-gradient(
+ rgba(45, 163, 246, 0) 0%,
+ rgba(45, 163, 246, 0) 23%,
+ rgba(45, 163, 246, 0.7) 24%,
+ rgba(45, 163, 246, 0) 25%
+ );
+ margin: 0 auto;
+ border-radius: 50%;
+ border: 2rpx solid rgba(45, 163, 246, 0.7);
+ overflow: hidden;
+}
+
+.radar::after {
+ content: "";
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: $dotSize;
+ height: $dotSize;
+ background: $maincolor;
+ margin-left: -1rpx;
+ margin-top: -1rpx;
+ border-radius: 1rpx;
+}
+
+.dot {
+ position: absolute;
+ width: $dotSize;
+ height: $dotSize;
+ background: $maincolor;
+ opacity: 0;
+ border-radius: 50%;
+ animation: breath 3s linear infinite;
+ box-shadow: 0 0 2rpx 2rpx rgba(45, 163, 246, 0.5);
+}
+
+.dot-1 {
+ top: 50rpx;
+ left: 30rpx;
+ animation-delay: 1s;
+}
+
+.dot-2 {
+ top: 60rpx;
+ right: 20rpx;
+ animation-delay: 0.2s;
+}
+
+.dot-3 {
+ top: 140rpx;
+ right: 100rpx;
+ animation-delay: 2.3s;
+}
+
+.cover {
+ transform-origin: bottom right;
+ border-right: 1rpx solid $maincolor;
+ background: linear-gradient(
+ 45deg,
+ rgba(255, 255, 255, 0) 45%,
+ $maincolor 100%
+ );
+ width: 50%;
+ height: 50%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ animation: rotation 3s linear infinite;
+}
+
+@keyframes rotation {
+ 0% {
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+@keyframes breath {
+ 0% {
+ opacity: 0;
+ }
+
+ 10% {
+ opacity: 1;
+ }
+
+ 20% {
+ opacity: 1;
+ }
+
+ 40% {
+ opacity: 0;
+ }
+
+ 100% {
+ opacity: 0;
+ }
+}
+</style>
diff --git a/uni_modules/zero-loading/components/zero-loading/static/loading-sun.vue b/uni_modules/zero-loading/components/zero-loading/static/loading-sun.vue
new file mode 100644
index 0000000..ed079d8
--- /dev/null
+++ b/uni_modules/zero-loading/components/zero-loading/static/loading-sun.vue
@@ -0,0 +1,140 @@
+<template>
+ <view class="animations">
+ <view class="box">
+ <view class="sun"></view>
+ <view class="orbit orbit1">
+ <view class="planetX planet1"></view>
+ </view>
+ <view class="orbit orbit2">
+ <view class="planetX planet2"></view>
+ </view>
+ <view class="orbit orbit3">
+ <view class="planetX planet3"></view>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+export default {
+ name: "loading-sun",
+ data() {
+ return {};
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+.box {
+ width: 210rpx;
+ height: 210rpx;
+ position: relative;
+}
+.sun {
+ background: radial-gradient(#ff0, #f90);
+ height: 50rpx;
+ width: 50rpx;
+ border-radius: 50%;
+ position: absolute;
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ margin: auto;
+}
+
+.planetX {
+ position: absolute;
+ z-index: 100;
+ border-radius: 50%;
+}
+
+.planet1 {
+ left: 20rpx;
+ height: 13rpx;
+ width: 13rpx;
+ background-color: #fed313;
+}
+
+.planet2 {
+ left: 23rpx;
+ height: 20rpx;
+ width: 20rpx;
+ background: linear-gradient(#00ff00, #09f, #09f);
+ -webkit-animation: rotation 1s infinite linear;
+ animation: rotation 1s infinite linear;
+}
+
+.planet3 {
+ left: 49rpx;
+ height: 17rpx;
+ width: 17rpx;
+ background: radial-gradient(#ff9900, #ff4400);
+}
+
+.orbit {
+ background: transparent;
+ border-radius: 50%;
+ border: 1rpx solid #cccccc;
+ position: absolute;
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ margin: auto;
+}
+
+.orbit1 {
+ height: 100rpx;
+ width: 100rpx;
+ -webkit-animation: rotation 2s infinite linear;
+ -moz-animation: rotation 2s infinite linear;
+ animation: rotation 2s infinite linear;
+}
+
+.orbit2 {
+ height: 150rpx;
+ width: 150rpx;
+ -webkit-animation: rotation 3s infinite linear;
+ -moz-animation: rotation 3s infinite linear;
+ animation: rotation 3s infinite linear;
+}
+
+.orbit3 {
+ height: 200rpx;
+ width: 200rpx;
+ -moz-animation: rotation 6s infinite linear;
+ -webkit-animation: rotation 6s infinite linear;
+ animation: rotation 6s infinite linear;
+}
+
+@-webkit-keyframes rotation {
+ from {
+ -webkit-transform: rotate(0deg);
+ }
+
+ to {
+ -webkit-transform: rotate(359deg);
+ }
+}
+
+@keyframes rotation {
+ from {
+ transform: rotate(0deg);
+ }
+
+ to {
+ transform: rotate(359deg);
+ }
+}
+
+@-moz-keyframes rotation {
+ from {
+ -moz-transform: rotate(0deg);
+ }
+
+ to {
+ -moz-transform: rotate(359deg);
+ }
+}
+</style>
diff --git a/uni_modules/zero-loading/components/zero-loading/static/loading-surround.vue b/uni_modules/zero-loading/components/zero-loading/static/loading-surround.vue
new file mode 100644
index 0000000..0e47a11
--- /dev/null
+++ b/uni_modules/zero-loading/components/zero-loading/static/loading-surround.vue
@@ -0,0 +1,91 @@
+<template>
+ <view class="animations">
+ <view class="box">
+ <view class="loader">
+ <view class="loader__ball"></view>
+ <view class="loader__ball"></view>
+ <view class="loader__ball"></view>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+export default {
+ name: "loading-triangle",
+ data() {
+ return {};
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+$dotColor: linear-gradient(135deg, #1fa2ff, #12d8fa, #29ffc6);
+$dotSize: 30rpx;
+$duration: 2s;
+.animations {
+ width: 160rpx;
+ height: 160rpx;
+ position: relative;
+}
+.box {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+}
+.loader {
+ animation: rotate $duration linear infinite normal;
+ position: relative;
+ transform-origin: 50% 50%;
+
+ &__ball {
+ height: $dotSize;
+ width: $dotSize;
+ left: -$dotSize * 0.5;
+ position: absolute;
+ top: -$dotSize * 0.5;
+ transform-origin: 50% 50%;
+
+ &:nth-of-type(2) {
+ transform: rotate(120deg);
+ }
+
+ &:nth-of-type(3) {
+ transform: rotate(240deg);
+ }
+
+ &::after {
+ animation: move $duration * 0.5 ease-in-out infinite alternate;
+ background: $dotColor;
+ border-radius: 50%;
+ content: "";
+ display: inline-block;
+ height: 100%;
+ width: 100%;
+ transform-origin: 50% 50%;
+ }
+ }
+}
+
+@keyframes rotate {
+ from {
+ transform: rotate(0);
+ }
+
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+@keyframes move {
+ 0%,
+ 15% {
+ transform: translateY(0);
+ }
+
+ 100% {
+ transform: translateY(-150%);
+ }
+}
+</style>
diff --git a/uni_modules/zero-loading/components/zero-loading/static/loading-sword.vue b/uni_modules/zero-loading/components/zero-loading/static/loading-sword.vue
new file mode 100644
index 0000000..8efb848
--- /dev/null
+++ b/uni_modules/zero-loading/components/zero-loading/static/loading-sword.vue
@@ -0,0 +1,81 @@
+<template>
+ <view class="animations">
+ <view class="box" :style="{ '--color': color }">
+ <view class="sword"></view>
+ <view class="sword"></view>
+ <view class="sword"></view>
+ </view>
+ </view>
+</template>
+
+<script>
+export default {
+ name: "loading-sword",
+ props: {
+ color: {
+ type: String,
+ default: "#ED213A",
+ },
+ },
+ data() {
+ return {};
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+.box {
+ position: relative;
+ width: 120rpx;
+ height: 120rpx;
+}
+.sword {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ border-radius: 50%;
+}
+.sword:nth-of-type(1) {
+ left: 0%;
+ top: 0%;
+ border-bottom: 8rpx solid var(--color);
+ animation: sword1 0.8s linear infinite;
+}
+.sword:nth-of-type(2) {
+ right: 0%;
+ top: 0%;
+ border-right: 8rpx solid var(--color);
+ animation: sword2 0.8s linear infinite;
+}
+.sword:nth-of-type(3) {
+ right: 0%;
+ bottom: 0%;
+ border-top: 8rpx solid var(--color);
+ animation: sword3 0.8s linear infinite;
+}
+@keyframes sword1 {
+ 0% {
+ transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg);
+ }
+ 100% {
+ transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg);
+ }
+}
+@keyframes sword2 {
+ 0% {
+ transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg);
+ }
+ 100% {
+ transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg);
+ }
+}
+
+@keyframes sword3 {
+ 0% {
+ transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg);
+ }
+ 100% {
+ transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg);
+ }
+}
+</style>
diff --git a/uni_modules/zero-loading/components/zero-loading/static/loading-wobble.vue b/uni_modules/zero-loading/components/zero-loading/static/loading-wobble.vue
new file mode 100644
index 0000000..d8f6283
--- /dev/null
+++ b/uni_modules/zero-loading/components/zero-loading/static/loading-wobble.vue
@@ -0,0 +1,127 @@
+<template>
+ <view class="animations">
+ <view class="three-body" :style="{ '--color': color }">
+ <view class="three-body__dot"></view>
+ <view class="three-body__dot"></view>
+ <view class="three-body__dot"></view>
+ </view>
+ </view>
+</template>
+
+<script>
+export default {
+ name: "loading-wobble",
+ props: {
+ color: {
+ type: String,
+ default: "#0396FF",
+ },
+ },
+ data() {
+ return {};
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+$size: 100rpx;
+$speed: 1s;
+.three-body {
+ position: relative;
+ display: inline-block;
+ height: $size;
+ width: $size;
+ animation: spin78236 calc($speed * 2.5) infinite linear;
+}
+
+.three-body__dot {
+ position: absolute;
+ height: 100%;
+ width: 27%;
+}
+
+.three-body__dot:after {
+ content: "";
+ position: absolute;
+ height: 0%;
+ width: 100%;
+ padding-bottom: 100%;
+ background-color: var(--color);
+ border-radius: 50%;
+}
+
+.three-body__dot:nth-child(1) {
+ bottom: 5%;
+ left: 0;
+ transform: rotate(60deg);
+ transform-origin: 50% 85%;
+}
+
+.three-body__dot:nth-child(1)::after {
+ bottom: 0;
+ left: 0;
+ animation: wobble1 $speed infinite ease-in-out;
+ animation-delay: calc($speed * -0.3);
+}
+
+.three-body__dot:nth-child(2) {
+ bottom: 5%;
+ right: 0;
+ transform: rotate(-60deg);
+ transform-origin: 50% 85%;
+}
+
+.three-body__dot:nth-child(2)::after {
+ bottom: 0;
+ left: 0;
+ animation: wobble1 $speed infinite calc($speed * -0.15) ease-in-out;
+}
+
+.three-body__dot:nth-child(3) {
+ bottom: -5%;
+ left: 0;
+ transform: translateX(116.666%);
+}
+
+.three-body__dot:nth-child(3)::after {
+ top: 0;
+ left: 0;
+ animation: wobble2 $speed infinite ease-in-out;
+}
+
+@keyframes spin78236 {
+ 0% {
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+@keyframes wobble1 {
+ 0%,
+ 100% {
+ transform: translateY(0%) scale(1);
+ opacity: 1;
+ }
+
+ 50% {
+ transform: translateY(-66%) scale(0.65);
+ opacity: 0.8;
+ }
+}
+
+@keyframes wobble2 {
+ 0%,
+ 100% {
+ transform: translateY(0%) scale(1);
+ opacity: 1;
+ }
+
+ 50% {
+ transform: translateY(66%) scale(0.65);
+ opacity: 0.8;
+ }
+}
+</style>
diff --git a/uni_modules/zero-loading/components/zero-loading/zero-loading.vue b/uni_modules/zero-loading/components/zero-loading/zero-loading.vue
new file mode 100644
index 0000000..62db5eb
--- /dev/null
+++ b/uni_modules/zero-loading/components/zero-loading/zero-loading.vue
@@ -0,0 +1,186 @@
+<template>
+ <!-- -->
+ <view
+ :style="{ position: position, 'z-index': zIndex, '--opacity': maskOpacity }"
+ class="container"
+ :class="[
+ mask ? 'mask' : '',
+ maskMini ? 'mask-mini' : '',
+ (mask || maskMini) && maskDark ? 'mask-dark' : '',
+ ]"
+ @click.prevent="handleClick"
+ >
+ <view>
+ <view class="main">
+ <loading0 v-if="type == 'circle'" :color="color"></loading0>
+ <loading1 v-if="type == 'pulse'" :color="color"></loading1>
+ <loading2 v-if="type == 'bounce'"></loading2>
+ <loading3 v-if="type == 'eyes'"></loading3>
+ <loading4 v-if="type == 'surround'"></loading4>
+ <loading5 v-if="type == 'sun'"></loading5>
+ <loading6 v-if="type == 'love'"></loading6>
+ <loading7 v-if="type == 'sword'" :color="color"></loading7>
+ <loading8 v-if="type == 'atom'" :color="color"></loading8>
+ <loading9 v-if="type == 'gear'"></loading9>
+ <loading10 v-if="type == 'radar'"></loading10>
+ <loading11 v-if="type == 'annulus'" :color="color"></loading11>
+ <loading12 v-if="type == 'wobble'" :color="color"></loading12>
+ <loading13 v-if="type == 'equal'" :color="color"></loading13>
+ <loading14 v-if="type == 'photo'" :color="color"></loading14>
+ <loading15 v-if="type == 'locating'" :color="color"></loading15>
+ </view>
+ <view
+ class="tips"
+ v-if="showText"
+ :style="{ color: textColor, fontSize: textSize, marginTop: textGap }"
+ >{{ text }}</view
+ >
+ </view>
+ </view>
+</template>
+
+<script>
+import loading0 from "./static/loading-circle.vue";
+import loading1 from "./static/loading-pulse.vue";
+import loading2 from "./static/loading-bounce.vue";
+import loading3 from "./static/loading-eyes.vue";
+import loading4 from "./static/loading-surround.vue";
+import loading5 from "./static/loading-sun.vue";
+import loading6 from "./static/loading-love.vue";
+import loading7 from "./static/loading-sword.vue";
+import loading8 from "./static/loading-atom.vue";
+import loading9 from "./static/loading-gear.vue";
+import loading10 from "./static/loading-radar.vue";
+import loading11 from "./static/loading-annulus.vue";
+import loading12 from "./static/loading-wobble.vue";
+import loading13 from "./static/loading-equal.vue";
+import loading14 from "./static/loading-photo.vue";
+import loading15 from "./static/loading-locating.vue";
+
+export default {
+ name: "zero-loading",
+ components: {
+ loading0,
+ loading1,
+ loading2,
+ loading3,
+ loading4,
+ loading5,
+ loading6,
+ loading7,
+ loading8,
+ loading9,
+ loading10,
+ loading11,
+ loading12,
+ loading13,
+ loading14,
+ loading15,
+ },
+ props: {
+ type: {
+ type: String,
+ default: "atom",
+ },
+ position: {
+ type: String,
+ default: "fixed",
+ },
+ zIndex: {
+ type: Number,
+ default: 9,
+ },
+ mask: {
+ type: Boolean,
+ default: false,
+ },
+ maskOpacity: {
+ type: Number,
+ default: 0.1,
+ },
+ maskMini: {
+ type: Boolean,
+ default: false,
+ },
+ maskDark: {
+ type: Boolean,
+ default: true,
+ },
+ color: {
+ type: String,
+ default: "#0396FF",
+ },
+ showText: {
+ type: Boolean,
+ default: false,
+ },
+ text: {
+ type: String,
+ default: "鍔犺浇涓�...",
+ },
+ textSize: {
+ type: String,
+ default: "28rpx",
+ },
+ textColor: {
+ type: String,
+ default: "#333333",
+ },
+ textGap: {
+ type: String,
+ default: "40rpx",
+ },
+ },
+ data() {
+ return {};
+ },
+ methods: {
+ handleClick() {
+ this.$emit("click");
+ },
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+.container {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+.tips {
+ // margin-top: 40rpx;
+ text-align: center;
+}
+
+.mask {
+ z-index: 999 !important;
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ height: 100vh;
+ width: 100vw;
+ background: rgba(255, 255, 255, var(--opacity));
+ transform: translate(0, 0);
+}
+
+.mask-mini {
+ height: 300rpx;
+ width: 300rpx;
+ border-radius: 20rpx;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+}
+
+.mask-dark {
+ background: rgba(7, 17, 27, var(--opacity));
+}
+</style>
diff --git a/uni_modules/zero-loading/package.json b/uni_modules/zero-loading/package.json
new file mode 100644
index 0000000..17f7d3e
--- /dev/null
+++ b/uni_modules/zero-loading/package.json
@@ -0,0 +1,83 @@
+{
+ "id": "zero-loading",
+ "displayName": "zero-loading(鍔犺浇鍔ㄧ敾)",
+ "version": "1.4.2",
+ "description": "绾痗ss鍔犺浇鍔ㄧ敾, 涓�涓爣绛惧厓绱犲嵆鍙疄鐜扮偒閰风殑鍏ㄥ睆loading鏁堟灉,鏀寔vue2,vue3",
+ "keywords": [
+ "loading",
+ "鍔犺浇鍔ㄧ敾",
+ "css鍔ㄧ敾",
+ "鍔犺浇"
+],
+ "repository": "",
+ "engines": {
+ "HBuilderX": "^3.1.0"
+ },
+"dcloudext": {
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "鏃�",
+ "data": "鎻掍欢涓嶉噰闆嗕换浣曟暟鎹�",
+ "permissions": "鏃�"
+ },
+ "npmurl": "",
+ "type": "component-vue"
+ },
+ "uni_modules": {
+ "dependencies": [],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y",
+ "alipay": "n"
+ },
+ "client": {
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ },
+ "App": {
+ "app-vue": "u",
+ "app-nvue": "u",
+ "app-harmony": "u",
+ "app-uvue": "u"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "寰俊娴忚鍣�(Android)": "y",
+ "QQ娴忚鍣�(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "u",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "灏忕▼搴�": {
+ "寰俊": "y",
+ "闃块噷": "u",
+ "鐧惧害": "u",
+ "瀛楄妭璺冲姩": "u",
+ "QQ": "u"
+ },
+ "蹇簲鐢�": {
+ "鍗庝负": "u",
+ "鑱旂洘": "u"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/zero-loading/readme.md b/uni_modules/zero-loading/readme.md
new file mode 100644
index 0000000..2f14f69
--- /dev/null
+++ b/uni_modules/zero-loading/readme.md
@@ -0,0 +1,69 @@
+# zero-loading
+
+> 浠呮祴璇曚簬 vue2, vue3, 寰俊灏忕▼搴�. 鍏朵粬骞冲彴鑷娴嬭瘯
+
+## 浣跨敤鏂规硶
+
+瀵煎叆 `uni_modules` 鍚庣洿鎺ヤ娇鐢ㄥ嵆鍙�
+
+鎻愪緵澶氱鍔犺浇鍔ㄧ敾绫诲瀷,浼犲叆 type 鏀瑰彉 loading 鏍峰紡锛屼笉浼犻粯璁� circle
+
+### 鍏ㄥ睆浣跨敤
+
+```html
+<zero-loading v-if="loading"></zero-loading>
+```
+
+### 灞�閮ㄤ娇鐢�
+
+**鐖跺厓绱犵殑 `position` 璁板緱鏀逛负 `relative` 涓嶇劧鍙兘褰卞搷鏁堟灉**
+
+```html
+<zero-loading type="pulse" position="absolute"></zero-loading>
+```
+
+## 鍙傛暟璇存槑
+
+| 鍙傛暟 | 绫诲瀷 | 榛樿鍊� | 鎻忚堪 |
+| ----------- | -------- | --------- | ---------------------------------------------- |
+| type | String | atom | 鏍峰紡 |
+| position | String | fixed | 瀹氫綅鏂瑰紡 |
+| zIndex | Number | 9 | |
+| mask | Boolean | false | 鏄惁闇�瑕侀伄缃� (榛樿涓哄叏灞忛伄缃�,鑳屾櫙鑹查粯璁や负榛戣壊) |
+| maskOpacity | Number | 0.1 | 閬僵閫忔槑搴� |
+| maskMini | Boolean | false | 浼犲叆 true 鏃�,浣跨敤灏忛伄缃� |
+| maskDark | Boolean | true | 浼犲叆 false 鏃�,閬僵鑳屾櫙鑹蹭负鐧借壊 |
+| color | String | #0396FF | 鑷畾涔夐鑹�,浠呴儴鍒嗘敮鎸� |
+| showText | showText | false | 鏄惁鏄剧ず鏂囧瓧 |
+| text | String | 鍔犺浇涓�... | 鏂囨湰鍐呭 |
+| textSize | String | 28rpx | 鏂囧瓧澶у皬 |
+| textColor | String | #333333 | 鏂囧瓧棰滆壊 |
+| textGap | String | 40rpx | 鏂囧瓧涓� loading 鍔ㄧ敾鐨勯棿璺� |
+
+### type 鍙�夊�硷細
+
+| type 鍊� | 鎻忚堪 |
+| -------- | ----------------- |
+| locating | 瀹氫綅 (鑷畾涔夐鑹�) |
+| photo | 鐓х墖 (鑷畾涔夐鑹�) |
+| equal | 绛夎竟 (鑷畾涔夐鑹�) |
+| wobble | 鎽囨憜 (鑷畾涔夐鑹�) |
+| annulus | 鍦嗙幆 (鑷畾涔夐鑹�) |
+| sword | 鍓戞皵 (鑷畾涔夐鑹�) |
+| atom | 鍘熷瓙 (鑷畾涔夐鑹�) |
+| pulse | 鑴夊啿 (鑷畾涔夐鑹�) |
+| circle | 鍦嗗湀 (鑷畾涔夐鑹�) |
+| eyes | 鐪肩潧 |
+| surround | 鐜粫 |
+| bounce | 寮硅烦 |
+| radar | 闆疯揪 |
+| gear | 榻胯疆 |
+| love | 鐖卞績 |
+| sun | 澶槼 |
+
+鎻掍欢棰勮:
+
+
+> 灏忕▼搴忔悳绱�: 闆舵妧鏈�
+
+> 棰勮鐨勫皬绋嬪簭涓嶄竴瀹氳兘鍙婃椂鏇存柊褰撳墠鎻掍欢
--
Gitblit v1.8.0