1789 lines
95 KiB
Plaintext
1789 lines
95 KiB
Plaintext
<template>
|
||
<view :class="theme_view" :style="width_height_style">
|
||
<view v-if="video_data_list && video_data_list.length > 0" class="content pr" :style="width_height_style">
|
||
<!-- 视频列表 -->
|
||
<view class="swiper" ref="swiper">
|
||
<block v-for="(video_item, index) in video_data_list" :key="video_item.id">
|
||
<view class="pr" @tap.stop="toggle_play_pause" :style="width_height_style" @touchstart.prevent="ListTouchStart" @touchmove.prevent="ListTouchMove">
|
||
<view class="video-bg" :style="width_height_style">
|
||
<template v-if="!isEmpty(video_item.cover)">
|
||
<image class="video-bg-image" :style="width_height_style" :src="video_item.cover" mode="scaleToFill"></image>
|
||
</template>
|
||
</view>
|
||
|
||
<video class="video" :style="width_height_style + swiperStyle" :src="video_item.video_url" :poster="video_item.cover" :id="`video_${index}`" :loop="true" :show-fullscreen-btn="false" :show-center-play-btn="false" :show-play-btn="false" :controls="false" :show-mute-btn="true" object-fit="contain" @timeupdate="handle_time_update" @play="handle_play" @tap.stop="toggle_play_pause"></video>
|
||
|
||
<view v-if="paused && current_index == index" class="play-icon" :style="width_height_style + swiperStyle">
|
||
<view class="flex-1 pr flex-row align-c jc-c">
|
||
<view class="play-icon-bg"></view>
|
||
<view class="pa z-i">
|
||
<u-icon propName="bofang" propSize="120rpx" propColor="#4F3E35"></u-icon>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<template v-if="!show_comment_modal">
|
||
<!-- Right Action Bar -->
|
||
<view class="right-actions">
|
||
<view v-if="base_config_data && base_config_data.is_video_give_thumbs && base_config_data.is_video_give_thumbs == 1" class="action-item" :data-id="video_item.id" @tap.stop="handle_like">
|
||
<u-icon propName="givealike" propSize="60rpx" :propColor="video_item.is_give_thumbs == 0 ? '#fff' : '#F4B73F'"></u-icon>
|
||
<text class="action-text">{{ video_item.give_thumbs_count }}</text>
|
||
</view>
|
||
<view v-if="base_config_data && base_config_data.is_video_comments_show && base_config_data.is_video_comments_show == 1" class="action-item" :data-id="video_item.id" @tap.stop="handle_comment">
|
||
<u-icon propName="comment" propSize="60rpx" propColor="#fff"></u-icon>
|
||
<text class="action-text">{{ video_item.comments_count }}</text>
|
||
</view>
|
||
<view class="action-item" @tap.stop="handle_share">
|
||
<u-icon propName="share-solid" propSize="60rpx" propColor="#fff"></u-icon>
|
||
<text class="action-text">{{$t('common.share')}}</text>
|
||
</view>
|
||
</view>
|
||
<view v-if="!isEmpty(video_item.goods) && base_config_data && base_config_data.is_video_detail_show_goods && base_config_data.is_video_detail_show_goods == 1" class="product-card">
|
||
<view class="flex-col">
|
||
<view v-if="video_item.show_goods" class="flex-row align-c product-card-item mb-10" :data-id="video_item.id" @tap.stop="handle_product_card_item">
|
||
<view style="width: 100rpx;height:100rpx;">
|
||
<image :src="video_item.goods.images" mode="aspectFill" style="width: 100rpx;height:100rpx;"></image>
|
||
</view>
|
||
<view class="flex-1 flex-col align-sb jc-c ml-10">
|
||
<text class="product-name text-line-1 mb-10">{{ video_item.goods.title }}</text>
|
||
<text class="product-price">¥{{ video_item.goods.price }}</text>
|
||
</view>
|
||
<view class="product-close" :data-id="video_item.id" @tap.stop="product_close_event">
|
||
<u-icon propName="close" propSize="40rpx" propColor="#999"></u-icon>
|
||
</view>
|
||
</view>
|
||
<view class="product-button" :data-id="video_item.id" @tap.stop="handle_product_button">
|
||
<view class="product-button-left flex-row align-c">
|
||
<u-icon propName="cart-have" propSize="30rpx" propColor="#F5C366"></u-icon>
|
||
<text class="size-14 cr-f ml-10">{{$t('common.buy')}} {{$t('common.goods')}}</text>
|
||
</view>
|
||
<u-icon propName="angle-right" propSize="30rpx" propColor="#fff"></u-icon>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- Progress Bar -->
|
||
<view class="progress-bar-container" v-if="current_index == index" :style="'width: ' + (windowWidth - 20) + 'px'">
|
||
<slider class="flex-1 progress-slider" :value="current_video_progress" :max="current_video_duration" @change.stop="handle_slider_change" @changing="handle_slider_changing" @tap.stop="handle_slider_change" block-size="14" activeColor="#FFFFFF" backgroundColor="rgba(255, 255, 255, 0.4)" />
|
||
<text class="time-display">{{ format_time(current_video_progress) }} / {{ format_time(current_video_duration) }}</text>
|
||
</view>
|
||
</template>
|
||
</view>
|
||
</block>
|
||
</view>
|
||
<!-- 搜索框 -->
|
||
<view v-if="!show_comment_modal" class="header-top" :style="top_content_style + menu_button_info + ' width: ' + windowWidth + 'px;'">
|
||
<view id="search-height" class="flex-row align-c">
|
||
<!-- 支付宝小程序自带返回按钮,这里就不给返回按钮了,这里给留出一点空间就行 -->
|
||
<!-- #ifndef MP-ALIPAY -->
|
||
<view class="cp" @tap="handle_back">
|
||
<u-icon propName="arrow-left" propSize="36rpx" propColor="#bbb" class="mr-10"></u-icon>
|
||
</view>
|
||
<!-- #endif -->
|
||
<view class="flex-1" :style="header_padding_left">
|
||
<component-search propIsDisabled @disabledSearch="handle_search" :propsWidth="windowWidth" />
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<template v-else>
|
||
<component-no-data :propStatus="data_list_loding_status" :propMsg="data_list_loding_msg"></component-no-data>
|
||
</template>
|
||
|
||
<!-- 评论弹窗 -->
|
||
<view v-if="show_comment_modal" class="comment-modal" :style="width_height_style" @tap="close_comment_modal">
|
||
<view class="comment-content bottom-line-exclude-bottom" @tap="comment_modal_content" :style="commentContentStyle">
|
||
<view class="comment-header" data-type="header" @tap.stop @touchstart.prevent="handle_comment_touch_start" @touchmove.prevent="handle_comment_touch_move" @touchend="handle_comment_touch_end">
|
||
<text class="comment-count">{{$t('common.comment')}}</text>
|
||
<view class="close-btn" @tap="close_comment_modal">✕</view>
|
||
</view>
|
||
<view class="flex-1 flex-row oh" :style="'width:' + windowWidth + 'px;'" data-type="scroll" @tap.stop @touchstart.prevent="handle_comment_touch_start" @touchmove.prevent="handle_comment_touch_move" @touchend="handle_comment_touch_end">
|
||
<!-- 评论内容区域 -->
|
||
<!-- <scroll-view class="flex-1 comment-list flex-row" scroll-y :scroll-top="comment_scroll_top" show-scrollbar="false" scroll-with-animation :scroll-with-touch="!is_dragging" @scrolltolower="handle_comment_to_lower_scroll" @scroll="handle_comment_scroll"> -->
|
||
<list class="comment-list comment-scroll" :show-scrollbar="false" :scrollable="!is_dragging" loadmoreoffset="100" @scroll="handle_comment_scroll" @loadmore="handle_comment_to_lower_scroll">
|
||
<template v-if="active_comments && active_comments.length > 0">
|
||
<cell v-for="(comment_item, index) in active_comments" :key="comment_item.id">
|
||
<view class="comment-item flex-col">
|
||
<commentInfoComponent :style="window_more_style" :propComment="comment_item" :propId="comment_item.id" :propDropDownVisible="active_dropdown_id == comment_item.id" @comment_reply="comment_reply" @comment_like="comment_like" @toggle_dropdown="handle_toggle_dropdown" @dropdown_item_click="handle_dropdown_item_click"></commentInfoComponent>
|
||
<!-- 子评论 -->
|
||
<view class="sub-comment flex-col jc-c mt-10">
|
||
<view v-if="comment_item.sub_comments && Array.isArray(comment_item.sub_comments) && comment_item.sub_comments.length > 0 && comment_item.show_sub_comment" style="margin-buttom: 20rpx;" class="sub-comment-list flex-col jc-c">
|
||
<view v-for="(sub_comment_item, sub_comment_index) in comment_item.sub_comments" :key="sub_comment_index" class="sub-comment-item flex-row align-s" style="margin-bottom: 20rpx;">
|
||
<commentInfoComponent :style="window_sub_more_style" :propComment="sub_comment_item" :propId="sub_comment_item.id" :propDropDownVisible="active_dropdown_id == sub_comment_item.id" @comment_reply="comment_reply" @comment_like="comment_like" @toggle_dropdown="handle_toggle_dropdown" @dropdown_item_click="handle_dropdown_item_click"></commentInfoComponent>
|
||
</view>
|
||
</view>
|
||
<template v-if="comment_item.comments_count > 0">
|
||
<template v-if="!comment_item.show_sub_comment">
|
||
<commentMoreComponent :style="window_more_style" :propId="comment_item.id" :propIsLevel="1" :propText="'—— '+ $t('common.expand') + (comment_item.comments_count ? comment_item.comments_count || 0 : 0) + $t('ask-comments.ask-comments.ymmd24')" @comment_more_event="open_sub_comment"></commentMoreComponent>
|
||
</template>
|
||
<template v-else>
|
||
<template v-if="comment_item.show_sub_comment_loading">
|
||
<loading-component :style="window_more_style"></loading-component>
|
||
</template>
|
||
<view v-else class="sub-comment-more flex-row align-c gap-10">
|
||
<template v-if="comment_item.page != null && comment_item.page < comment_item.page_total">
|
||
<commentMoreComponent :style="window_more_style" :propId="comment_item.id" :propIsLevel="2" :propText="$t('common.expand')" @comment_more_event="open_sub_comment"></commentMoreComponent>
|
||
</template>
|
||
<commentMoreComponent :style="window_more_style" :propId="comment_item.id" :propText="$t('common.retract')" propIconName="arrow-top" @comment_more_event="close_sub_comment"></commentMoreComponent>
|
||
</view>
|
||
</template>
|
||
</template>
|
||
</view>
|
||
</view>
|
||
</cell>
|
||
<template v-if="comment_item_loading">
|
||
<cell>
|
||
<view class="flex-row align-c jc-c" :style="window_more_style">
|
||
<component-loading></component-loading>
|
||
</view>
|
||
</cell>
|
||
</template>
|
||
<template v-else>
|
||
<cell>
|
||
<!-- 结尾 -->
|
||
<component-bottom-line :propStatus="goods_bottom_line_status"></component-bottom-line>
|
||
</cell>
|
||
</template>
|
||
</template>
|
||
<template v-else>
|
||
<cell>
|
||
<view class="flex-row align-c jc-c" :style="window_more_style">
|
||
<component-no-data :propMsg="$t('common.no_data')"></component-no-data>
|
||
</view>
|
||
</cell>
|
||
</template>
|
||
<!-- </view> -->
|
||
</list>
|
||
</view>
|
||
|
||
<view v-if="base_config_data && base_config_data.is_video_comments_add && base_config_data.is_video_comments_add == 1" class="comment-input-container">
|
||
<view class="flex-1 flex-col align-c">
|
||
<view v-if="!isEmpty(comments_reply_data)" class="comment-reply-content flex-row align-c jc-sb" :style="window_more_style">
|
||
<text class="size-12 cr-f text-line-1 mr-10">@{{ isEmpty(comments_reply_data.user) ? '' : comments_reply_data.user.user_name_view }}:{{ comments_reply_data.content }}</text>
|
||
<view data-type="image" @tap="comment_data_delete">
|
||
<u-icon propName="close-line" propSize="24rpx" propColor="#fff"></u-icon>
|
||
</view>
|
||
</view>
|
||
<view class="flex-row align-s pt-4" :style="window_more_style">
|
||
<view class="flex-1 comment-input-content flex-col jc-c">
|
||
<view class="flex-row align-s pr-16 box-border-box" @tap="add_comment">
|
||
<text :class="'flex-1 comment-input text-line-1 ' + (isEmpty(comment_input_value) ? 'cr-grey' : 'cr-black')">{{ isEmpty(comment_input_value) ? $t('video-detail.video-detail.98yyuf') : comment_input_value }}</text>
|
||
<view class="pt-8" @tap="upload_tap">
|
||
<component-upload :propMaxNum="propMaxNum" :propPathType="editor_path_type" propSlot propSingleCall propIsAllInfo @callBack="upload_images_event">
|
||
<u-icon propName="layout-module-single-images" propSize="40rpx" propColor="#999"></u-icon>
|
||
</component-upload>
|
||
</view>
|
||
</view>
|
||
<view v-if="form_images_list && form_images_list.length > 0" class="pr w h comment-input-img-container">
|
||
<view v-for="(item, index) in form_images_list" :key="index" class="comment-input-img pr">
|
||
<image :src="item.url" :data-index="index" @tap="upload_show_event" mode="aspectFill" class="comment-input-img"></image>
|
||
<view class="form-img-icon flex-row align-c jc-c" @tap="comment_input_img_close">
|
||
<u-icon propName="close" propSize="30rpx" propColor="#000" class="flex-row align-c jc-c" :data-index="index"></u-icon>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view v-if="!isEmpty(comment_input_value)" class="pt-4 flex-row align-c ml-10">
|
||
<button size="mini" type="default" class="margin-0 bg-main cr-white" @tap="send_comment">{{$t('common.send')}}</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 举报弹窗 -->
|
||
<u-popup ref="popupReportRef" propMode="bottom" propCloseType="text" :propWidth="'width:' + windowWidth + 'px;'" propTitleBorder class="pointer-events-auto" :propTitle="$t('video-detail.video-detail.rfsdfg')" :propCloseable="true" @close="popup_report_close_event" @callBack="submit_report">
|
||
<view class="report-content">
|
||
<!-- 主要内容区域 -->
|
||
<view class="report-body">
|
||
<!-- 第一层:举报原因选择 -->
|
||
<view v-if="report_type_list && report_type_list.length > 0" class="report-section">
|
||
<view class="report-label flex-row align-c">{{$t('video-detail.video-detail.rfsdfg')}}<text class="ml-10 report-required">*</text></view>
|
||
<view class="flex-row align-c flex-wrap">
|
||
<radio-group class="flex-row align-c flex-wrap" :style="window_more_style" @change="select_main_reason">
|
||
<label v-for="(mainItem, main_index) in report_type_list" :key="main_index" class="flex-row align-c mr-10">
|
||
<view class="flex-row align-c">
|
||
<radio :value="main_index.toString()" :checked="current_main_index === main_index" style="transform:scale(0.7)" />
|
||
<text class="report-name flex-row align-c">{{mainItem.name}}</text>
|
||
</view>
|
||
</label>
|
||
</radio-group>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 第二层:具体类型选择(当有主类别选中时显示) -->
|
||
<view class="report-section mt-20" v-if="current_main_index >= 0 && report_type_list[current_main_index] && report_type_list[current_main_index].data">
|
||
<view class="report-label flex-row align-c">{{$t('video-detail.video-detail.fsdf33')}}<text class="ml-10 report-required">*</text></view>
|
||
<view class="flex-row align-c flex-wrap">
|
||
<radio-group class="flex-row align-c flex-wrap" :style="window_more_style" @change="select_sub_reason">
|
||
<label v-for="(subItem, sub_index) in report_type_list[current_main_index].data" :key="sub_index" class="flex-row align-c mr-10">
|
||
<view class="flex-row align-c">
|
||
<radio :value="sub_index.toString()" :checked="current_sub_index === sub_index" style="transform:scale(0.7)" />
|
||
<text class="report-name flex-row align-c">{{subItem}}</text>
|
||
</view>
|
||
</label>
|
||
</radio-group>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</u-popup>
|
||
<!-- 添加评论弹出框 -->
|
||
<view v-if="is_add_comment" class="keyboard-input br-top-shadow" :style="'width:'+ windowWidth +'px;bottom:' + listener_height + 'px;'">
|
||
<view class="flex-1 flex-col">
|
||
<view class="comment-input-content flex-col jc-c">
|
||
<view v-if="!isEmpty(comments_reply_data)" class="comment-reply-content flex-row align-c jc-sb">
|
||
<text class="size-12 cr-f text-line-1 mr-10">@{{ comments_reply_data.user.user_name_view }}:{{ comments_reply_data.content }}</text>
|
||
<view data-type="image" @tap="comment_data_delete">
|
||
<u-icon propName="close-line" propSize="24rpx" propColor="#fff"></u-icon>
|
||
</view>
|
||
</view>
|
||
<view class="flex-row align-c pr-16 box-border-box">
|
||
<textarea ref="commentRef" :value="comment_input_value" :focus="is_add_comment" class="comment-input mr-10 cr-black" placeholder-class="cr-grey" auto-height maxlength="500" :show-confirm-bar="false" :adjust-position="false" :placeholder="$t('video-detail.video-detail.98yyuf')" @input="comment_input_event" @confirm="send_comment" />
|
||
</view>
|
||
<view v-if="form_images_list && form_images_list.length > 0" class="pr w h comment-input-img-container">
|
||
<view v-for="(item, index) in form_images_list" :key="index" class="comment-input-img pr">
|
||
<image :src="item.url" :data-index="index" @tap="upload_show_event" mode="aspectFill" class="comment-input-img"></image>
|
||
<view class="form-img-icon flex-row align-c jc-c" @tap="comment_input_img_close">
|
||
<u-icon propName="close" propSize="30rpx" propColor="#000" class="flex-row align-c jc-c" :data-index="index"></u-icon>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="flex-row align-c jc-sb pt-10">
|
||
<component-upload :propMaxNum="propMaxNum" :propPathType="editor_path_type" propSlot propSingleCall propIsAllInfo propChooseFocus @call-back="upload_images_event" @chooseFocus="upload_event">
|
||
<u-icon propName="layout-module-single-images" propSize="40rpx" propColor="#999"></u-icon>
|
||
</component-upload>
|
||
|
||
<button :disabled="isEmpty(comment_input_value)" size="mini" type="default" class="margin-0 bg-main cr-white" @tap="send_comment">{{$t('common.send')}}</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- 分享弹窗 -->
|
||
<u-share-popup ref="share" class="pointer-events-auto"></u-share-popup>
|
||
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
const app = getApp();
|
||
import { get_math, isEmpty, video_get_top_left_padding, showToast } from '@/common/js/common/common.js';
|
||
import commentInfoComponent from '@/pages/plugins/video/components/comment-info.vue';
|
||
import ComponentLoading from '@/pages/plugins/video/components/loading.vue';
|
||
import commentMoreComponent from '@/pages/plugins/video/components/comment-more.vue';
|
||
import ComponentSearch from '@/pages/plugins/video/components/search.vue';
|
||
import componentNoData from '@/components/no-data/no-data';
|
||
import componentBottomLine from '@/components/bottom-line/bottom-line';
|
||
import componentUpload from '@/components/upload/upload';
|
||
import scrollMixins from './scrollMixins';
|
||
// 多语言
|
||
//#ifdef APP-NVUE
|
||
const BindingX = uni.requireNativePlugin('bindingx');
|
||
const animation = weex.requireModule('animation');
|
||
const modal = weex.requireModule('modal');
|
||
import i18n from '@/locale/index.js';
|
||
// nvue页面在方法中使用时的处理
|
||
import { initVueI18n } from '@dcloudio/uni-i18n';
|
||
import indexNvue from '@/locale/index-nvue.js';
|
||
const { t } = initVueI18n(indexNvue)
|
||
//#endif
|
||
// 状态栏高度
|
||
var bar_height = parseInt(app.globalData.get_system_info('statusBarHeight', 0));
|
||
// #ifdef MP-TOUTIAO || H5
|
||
bar_height = 0;
|
||
// #endif
|
||
export default {
|
||
//#ifdef APP-NVUE
|
||
i18n,
|
||
//#endif
|
||
mixins:[scrollMixins],
|
||
data() {
|
||
return {
|
||
theme_view: app.globalData.get_theme_value_view(),
|
||
top_content_style: 'padding-top:' + bar_height + 'px;padding-bottom:10px;',
|
||
data_list_loding_status: 1,
|
||
data_list_loding_msg: '',
|
||
video_data_list: [],
|
||
current_index: 0,
|
||
video_contexts: [], // 原生的video视频
|
||
create_video_contexts: [], // 使用uni.createVideoContext创建的视频上下文
|
||
paused: false,
|
||
current_video_progress: 0,
|
||
current_video_duration: 1,
|
||
is_seeking: false,
|
||
show_comment_modal: false,
|
||
active_comments: {},
|
||
comments_page: 1, // 当前评论页
|
||
comments_page_total: 5, // 评论总页数
|
||
goods_bottom_line_status: false, //评论页是否显示底部线
|
||
comment_item_loading: false,
|
||
comment_start_y: 0, // 评论开始拖拽位置
|
||
comment_current_y: 0, // 评论当前拖拽位置
|
||
move_distance: 0, // 评论拖拽距离
|
||
is_dragging: false, // 是否正在拖拽中
|
||
current_video_id: '', // 当前播放视频的 ID
|
||
comment_scroll_top: 0, // 评论滚动距离顶部的距离
|
||
comment_input_value: '',
|
||
propMaxNum: 1, // 上传数量
|
||
form_images_list: [],
|
||
share_info: {},
|
||
menu_button_info: '',
|
||
base_config_data: {},
|
||
comment_scroll_debounce_timer: null, // 评论滚动防抖定时器
|
||
comment_move_throttle_timer: null, // 评论拖拽节流定时器
|
||
// 添加下拉菜单状态管理
|
||
active_dropdown_id: null, // 当前显示下拉菜单的评论ID
|
||
params: {},
|
||
header_padding_left: '',
|
||
report_type_list: [], // 举报类型列表
|
||
popup_report_status: false, // 举报弹窗状态
|
||
current_main_index: 0, // 默认选中第一个举报原因
|
||
current_sub_index: 0, // 默认选中第一个具体类型
|
||
report_comment_id: '', // 举报的评论id
|
||
comment_value: '',
|
||
// 监听键盘高度变化事件
|
||
is_add_comment: false,
|
||
listener_height: 0,
|
||
comments_reply_data: {},
|
||
editor_path_type: 'video',
|
||
is_manual_pause: false, // 是否手动暂停
|
||
windowWidth: 0,
|
||
windowHeight: 0,
|
||
padding_width: 0,
|
||
sub_comment_padding_left: 0,
|
||
};
|
||
},
|
||
components: {
|
||
commentInfoComponent,
|
||
commentMoreComponent,
|
||
ComponentSearch,
|
||
componentNoData,
|
||
componentBottomLine,
|
||
ComponentLoading,
|
||
componentUpload
|
||
},
|
||
watch: {
|
||
// 监听路由变化
|
||
listener_height(e) {
|
||
if (e > 0) {
|
||
this.handle_comment_input_value();
|
||
} else {
|
||
this.is_add_comment = false;
|
||
}
|
||
}
|
||
},
|
||
computed: {
|
||
// 视频列表高度
|
||
swiperStyle() {
|
||
return this.show_comment_modal ? (this.move_distance > 0 ? `height: ${Math.round(this.windowHeight * 0.3) + this.move_distance}px;` : `height: ${Math.round(this.windowHeight * 0.3)}px;`) : `height: ${this.windowHeight}px;`;
|
||
},
|
||
// 评论内容区域高度
|
||
commentContentStyle() {
|
||
const baseHeight = Math.round(this.windowHeight * 0.7);
|
||
return this.show_comment_modal && this.move_distance > 0
|
||
? `transform: translateY(3px); width:${this.windowWidth}px; height: ${baseHeight - this.move_distance}px;`
|
||
: `transform: translateY(0); width:${this.windowWidth}px; height: ${baseHeight}px;`;
|
||
},
|
||
// 当前播放视频的索引
|
||
current_video_index() {
|
||
if (this.video_data_list && this.video_data_list.length > 0) {
|
||
return this.video_data_list.findIndex(item => item.id == this.current_video_id);
|
||
} else {
|
||
return -1;
|
||
}
|
||
},
|
||
close_circular() {
|
||
try {
|
||
if (this.video_data_list && this.video_data_list.length > 0) {
|
||
return this.video_data_list[0].id == this.current_video_id || this.video_data_list[this.video_data_list.length - 1].id == this.current_video_id;
|
||
} else {
|
||
return true
|
||
}
|
||
} catch {
|
||
console.log('close_circular');
|
||
}
|
||
},
|
||
width_height_style() {
|
||
return `width: ${ this.windowWidth }px;height: ${ this.windowHeight }px;`;
|
||
},
|
||
window_more_style() {
|
||
return `width: ${ this.windowWidth - this.padding_width }px;`
|
||
},
|
||
window_sub_more_style() {
|
||
return `width: ${ this.windowWidth - this.sub_comment_padding_left }px;`
|
||
}
|
||
},
|
||
onLoad(params) {
|
||
try {
|
||
// 调用公共事件方法
|
||
app.globalData.page_event_onload_handle(params);
|
||
|
||
// 设置参数
|
||
this.params = app.globalData.launch_params_handle(params);
|
||
} catch {
|
||
console.log('close_circular');
|
||
}
|
||
},
|
||
|
||
onShow() {
|
||
try {
|
||
const data = uni.getWindowInfo();
|
||
this.windowWidth = data.windowWidth > 800 ? 800 : data.windowWidth;
|
||
this.windowHeight = data.windowHeight;
|
||
// 调用公共事件方法
|
||
app.globalData.page_event_onshow_handle();
|
||
|
||
// 视频播放
|
||
if (!this.is_manual_pause && this.create_video_contexts && this.create_video_contexts[this.current_index]) {
|
||
this.video_play_event(this.create_video_contexts[this.current_index]);
|
||
}
|
||
|
||
// 公共onshow事件
|
||
if ((this.$refs.common || null) != null) {
|
||
this.$refs.common.on_show();
|
||
}
|
||
|
||
// 分享菜单处理
|
||
app.globalData.page_share_handle();
|
||
} catch {
|
||
console.log('close_circular');
|
||
}
|
||
},
|
||
|
||
onHide() {
|
||
// 清理所有视频资源
|
||
this.cleanup_all_videos();
|
||
},
|
||
mounted() {
|
||
try {
|
||
uni.$on('chooseFocus', (data) => {
|
||
this.upload_event();
|
||
})
|
||
|
||
uni.$on('callBack', (res) => {
|
||
this.upload_images_event(res);
|
||
})
|
||
// 初始化
|
||
this.init();
|
||
|
||
// 创建监听事件
|
||
this.bind_keyboard_listener();
|
||
} catch {
|
||
console.log('close_circular');
|
||
}
|
||
},
|
||
beforeDestroy() {
|
||
// 清理定时器
|
||
if (this.comment_scroll_debounce_timer) {
|
||
clearTimeout(this.comment_scroll_debounce_timer);
|
||
}
|
||
if (this.comment_move_throttle_timer) {
|
||
clearTimeout(this.comment_move_throttle_timer);
|
||
}
|
||
|
||
// 清理所有视频资源
|
||
this.cleanup_all_videos();
|
||
this.unbind_keyboard_listener();
|
||
uni.$off('chooseFocus');
|
||
uni.$off('callBack');
|
||
},
|
||
methods: {
|
||
isEmpty,
|
||
init() {
|
||
try {
|
||
// 小程序下,获取小程序胶囊的宽度
|
||
let menu_button_info = `max-width:${ this.windowWidth }px;`;
|
||
// #ifndef MP-TOUTIAO
|
||
// #ifdef MP
|
||
// 判断是否有胶囊
|
||
const is_current_single_page = app.globalData.is_current_single_page();
|
||
// 如果有胶囊的时候,做处理
|
||
if (is_current_single_page == 0) {
|
||
const custom = uni.getMenuButtonBoundingClientRect();
|
||
menu_button_info = `max-width:calc(${ this.windowWidth } - ${custom.width + 10}px);`;
|
||
}
|
||
// #endif
|
||
// #endif
|
||
// 视频详情页,需要添加 padding-left
|
||
let padding_left = '';
|
||
// #ifdef MP-ALIPAY
|
||
padding_left = video_get_top_left_padding();
|
||
// #endif
|
||
this.padding_width = app.globalData.rpx_to_px(30);
|
||
this.sub_comment_padding_left = app.globalData.rpx_to_px(80);
|
||
|
||
this.header_padding_left = padding_left;
|
||
this.menu_button_info = menu_button_info;
|
||
this.current_video_id = isEmpty(this.current_video_id) ? this.params.id : this.current_video_id;
|
||
|
||
this.get_video_detail(this.current_video_id);
|
||
|
||
//设置参数
|
||
this.typeX = false //开启左右滑动
|
||
this.playCount = 2 //剩余多少视频加载视频列表
|
||
this.startDistance = 5 //判断左右上下拖动的启动距离 px
|
||
this.minTime = 300 //判断快速滑动的时间,该时间内无视回弹距离判断
|
||
this.backDistance = 200 //判断上下滑动的回弹距离 px
|
||
} catch (error) {
|
||
console.error('init error:', error);
|
||
}
|
||
},
|
||
/*
|
||
* 获取视频详情
|
||
* @param {*} id 视频 id
|
||
*/
|
||
get_video_detail(id) {
|
||
try {
|
||
// 获取数据
|
||
uni.request({
|
||
url: app.globalData.get_request_url("detail", "index", "video"),
|
||
method: 'POST',
|
||
data: {
|
||
id: id
|
||
},
|
||
dataType: 'json',
|
||
success: res => {
|
||
try {
|
||
const data = res.data;
|
||
if (data.code == 0) {
|
||
const new_data = data.data;
|
||
// 数据更新
|
||
this.data_list_loding_status = 3;
|
||
this.video_data_list = [new_data.data];
|
||
this.report_type_list = new_data.report_type_list;
|
||
this.base_config_data = new_data.base_config_data;
|
||
this.editor_path_type = new_data.editor_path_type;
|
||
|
||
this.get_last_or_next_data_list(this.params.id, 0, 1);
|
||
} else {
|
||
this.data_list_loding_status = 0;
|
||
this.data_tabs_loding_msg = data.msg;
|
||
}
|
||
} catch {
|
||
console.error('get_video_detail error:', error);
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
this.data_list_loding_status = 2;
|
||
this.data_list_loding_msg = t('common_internet_error_tips');
|
||
}
|
||
});
|
||
} catch (error) {
|
||
console.error('get_video_detail error:', error);
|
||
}
|
||
},
|
||
/*
|
||
* 获取视频列表
|
||
* @param {*} id 视频 id
|
||
* @param {*} is_last 是否获取上一批数据
|
||
* @param {*} is_next 是否获取下一批数据
|
||
*/
|
||
get_last_or_next_data_list(id, is_last = 0, is_next = 0) {
|
||
try {
|
||
// 获取数据
|
||
uni.request({
|
||
url: app.globalData.get_request_url("lastnextdata", "index", "video"),
|
||
method: 'POST',
|
||
data: {
|
||
id: id,
|
||
is_last: is_last,
|
||
is_next: is_next,
|
||
},
|
||
dataType: 'json',
|
||
success: res => {
|
||
const data = res.data;
|
||
if (data.code == 0) {
|
||
const new_data = data.data;
|
||
// 第一次的数据
|
||
// let data_list = JSON.parse(JSON.stringify(this.video_data_list));
|
||
// 创建现有数据的 ID 映射表,用于快速去重
|
||
const existing_ids = new Map();
|
||
this.video_data_list.forEach(item => {
|
||
existing_ids.set(item.id, true);
|
||
});
|
||
|
||
if (is_next == 1 && new_data.next && new_data.next.length > 0) { // 下一页数据 - 去重处理
|
||
const unique_next = new_data.next.filter(item => !existing_ids.has(item.id));
|
||
if (unique_next.length > 0) {
|
||
this.video_data_list.push(...unique_next);
|
||
}
|
||
}
|
||
// 更新当前视频商品信息
|
||
const new_index = this.video_data_list.findIndex(item => item.id == this.params.id);
|
||
// 处理当前视频商品信息
|
||
this.video_data_list.forEach((item) => {
|
||
if (isEmpty(item.show_goods)) {
|
||
if (this.base_config_data && this.base_config_data.is_video_detail_show_goods_modal && this.base_config_data.is_video_detail_show_goods_modal == 1) {
|
||
item.show_goods = true;
|
||
} else {
|
||
item.show_goods = false;
|
||
}
|
||
}
|
||
});
|
||
// 更新所有视频信息
|
||
// this.video_data_list = this.video_data_list;
|
||
this.$set(this, 'video_data_list', this.video_data_list);
|
||
this.video_data_list.forEach((item, index) => {
|
||
// this.create_video_contexts[index] = uni.createVideoContext(`video_${index}`, this);
|
||
this.$set(this.create_video_contexts, index, uni.createVideoContext(`video_${index}`, this));
|
||
});
|
||
// 逻辑说明:当是最后一个视频且需要播放下一个时,根据数组长度和新索引计算新的当前索引
|
||
// - 数组长度 > 2 时:新索引是最后一个元素则返回 2,是倒数第二个则返回 1,否则返回 0
|
||
// - 数组长度 <= 2 时:返回 length - 1
|
||
// this.current_index = is_next == 1 ? new_index : this.current_index;
|
||
|
||
if (is_next == 1) {
|
||
setTimeout(() => {
|
||
// const index = this.video_data_list.findIndex(item => item.id == this.current_index);
|
||
if (this.create_video_contexts && this.create_video_contexts[this.current_index]) { // 当前播放的视频索引为 0
|
||
this.video_play_event(this.create_video_contexts[this.current_index], true);
|
||
}
|
||
}, 100);
|
||
}
|
||
}
|
||
}
|
||
});
|
||
} catch (error) {
|
||
console.error('get_last_or_next_data_list error:', error);
|
||
}
|
||
},
|
||
// 评论输入框内容改变一下,确保能正常展开
|
||
handle_comment_input_value() {
|
||
this.is_add_comment = true;
|
||
const data = this.comment_input_value;
|
||
this.comment_input_value = '';
|
||
setTimeout(() => {
|
||
this.comment_input_value = data;
|
||
}, 100);
|
||
},
|
||
// 实际的 swiper 切换处理逻辑
|
||
process_swiper_change(current) {
|
||
try {
|
||
// 先暂停所有视频,确保不会有后台播放
|
||
this.pause_all_videos_except(current);
|
||
|
||
const id = this?.video_data_list[current]?.id || '';
|
||
// 更新状态
|
||
this.paused = false;
|
||
this.current_index = current;
|
||
this.is_manual_pause = false;
|
||
this.current_video_progress = 0;
|
||
this.current_video_duration = 1;
|
||
this.is_seeking = false;
|
||
this.current_video_id = id; // 更新当前播放视频的ID
|
||
|
||
//#ifdef H5
|
||
// 使用URLSearchParams处理当前查询参数
|
||
const url = new URL(location.href);
|
||
url.searchParams.set('id', id);
|
||
// 替换URL路径,保持查询参数不变
|
||
const pathname = location.href?.split('?')[0] || '';
|
||
history.replaceState(null, '', pathname + url.search);
|
||
//#endif
|
||
// 获取视频详细信息
|
||
this.get_video_data_detail(id);
|
||
// 更新分享信息
|
||
this.update_share_info(this.video_data_list[this.current_video_index]);
|
||
setTimeout(() => {
|
||
this.play_current_video_safely(this.current_index);
|
||
}, 50);
|
||
} catch (error) {
|
||
console.error('process_swiper_change error:', error);
|
||
}
|
||
},
|
||
showToast(msg) {
|
||
app.globalData.showToast(msg);
|
||
},
|
||
// 批量暂停除指定索引外的所有视频
|
||
pause_all_videos_except(exceptIndex) {
|
||
try {
|
||
if (this.create_video_contexts && this.create_video_contexts.length > 0) {
|
||
// 暂停 uni.createVideoContext 创建的视频
|
||
this.create_video_contexts.forEach((context, index) => {
|
||
if (index !== exceptIndex && context) {
|
||
try {
|
||
context.pause();
|
||
} catch (error) {
|
||
console.warn(`暂停视频 ${index} 失败:`, error);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
} catch (error) {
|
||
console.error('pause_all_videos_except error:', error);
|
||
}
|
||
},
|
||
|
||
// 安全播放当前视频
|
||
play_current_video_safely(index) {
|
||
try {
|
||
// 优先使用 uni.createVideoContext
|
||
if (this.create_video_contexts && this.create_video_contexts[index]) {
|
||
this.video_play_event(this.create_video_contexts[index]);
|
||
return;
|
||
}
|
||
} catch (error) {
|
||
console.error('play_current_video_safely error:', error);
|
||
}
|
||
},
|
||
|
||
// 切换播放暂停
|
||
toggle_play_pause(e) {
|
||
try {
|
||
const currentIndex = this.current_index;
|
||
// 检查视频上下文是否存在
|
||
const videoContext = this.create_video_contexts[currentIndex] || this.video_contexts[currentIndex];
|
||
if (!videoContext) {
|
||
console.warn(`当前索引 ${currentIndex} 无可用视频上下文`);
|
||
e.stopPropagation();
|
||
return;
|
||
}
|
||
|
||
this.paused = !this.paused;
|
||
this.is_manual_pause = !this.paused;
|
||
|
||
if (this.paused) {
|
||
// 暂停当前视频
|
||
try {
|
||
videoContext.pause();
|
||
} catch (error) {
|
||
e.stopPropagation();
|
||
console.warn('暂停视频失败:', error);
|
||
}
|
||
} else {
|
||
// 播放当前视频
|
||
this.video_play_event(videoContext);
|
||
}
|
||
e.stopPropagation();
|
||
} catch (error) {
|
||
console.error('toggle_play_pause error:', error);
|
||
}
|
||
},
|
||
|
||
// 更新分享信息
|
||
update_share_info(data) {
|
||
try {
|
||
const info = {
|
||
title: data?.title || '',
|
||
desc: data?.desc || '',
|
||
path: '/pages/plugins/video/detail/detail',
|
||
query: 'id=' + this.current_video_id,
|
||
img: data.cover || ''
|
||
}
|
||
this.share_info = info;
|
||
// 分享菜单处理
|
||
app.globalData.page_share_handle(info);
|
||
|
||
// 更新页面标题
|
||
uni.setNavigationBarTitle({title: data.title});
|
||
} catch (error) {
|
||
console.error('update_share_info error:', error);
|
||
}
|
||
},
|
||
|
||
// 安全的视频播放事件处理
|
||
video_play_event(videoContext, is_first_play = false) {
|
||
try {
|
||
if (!videoContext) {
|
||
this.paused = true;
|
||
this.is_manual_pause = false;
|
||
return;
|
||
}
|
||
|
||
try {
|
||
if (is_first_play) {
|
||
//#ifdef H5
|
||
videoContext.play().catch((error) => {
|
||
this.paused = true;
|
||
this.is_manual_pause = false;
|
||
});
|
||
//#endif
|
||
//#ifndef H5
|
||
videoContext.play();
|
||
//#endif
|
||
} else {
|
||
videoContext.play();
|
||
}
|
||
} catch (error) {
|
||
console.error('视频播放异常:', error);
|
||
this.paused = true;
|
||
this.is_manual_pause = false;
|
||
}
|
||
} catch (error) {
|
||
console.error('video_play_event error:', error);
|
||
}
|
||
},
|
||
|
||
// 评论输入框事件
|
||
comment_input_event(e) {
|
||
try {
|
||
this.comment_input_value = e.detail.value;
|
||
} catch (error) {
|
||
console.error('comment_input_event error:', error);
|
||
}
|
||
},
|
||
// 阻止上传图片事件触发父级方法
|
||
upload_tap(e) {
|
||
e.stopPropagation()
|
||
},
|
||
|
||
// 图片上传回调
|
||
upload_images_event(res) {
|
||
try {
|
||
if((res || null) != null) {
|
||
// 存储上传图片内容
|
||
if (this.form_images_list.length > 0) {
|
||
this.form_images_list.splice(0, 1, { url: res.url, name: res.name, size: res.size });
|
||
} else {
|
||
// 存储上传图片内容
|
||
this.form_images_list.push({
|
||
url: res.url,
|
||
name: res.name,
|
||
size: res.size,
|
||
});
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.error('upload_images_event error:', error);
|
||
}
|
||
},
|
||
upload_event() {
|
||
setTimeout(() => {
|
||
this.handle_comment_input_value();
|
||
}, 100);
|
||
},
|
||
|
||
// 上传图片预览
|
||
upload_show_event(e) {
|
||
try {
|
||
const index = e?.currentTarget?.dataset?.index || 0;
|
||
uni.previewImage({
|
||
current: this?.form_images_list[index]?.url || '',
|
||
urls: this.form_images_list.map(item => item.url),
|
||
});
|
||
} catch (error) {
|
||
console.error('upload_show_event error:', error);
|
||
}
|
||
},
|
||
|
||
// 评论输入图片删除
|
||
comment_input_img_close(e) {
|
||
try {
|
||
const index = e?.currentTarget?.dataset?.index || 0;
|
||
var list = this.form_images_list;
|
||
list.splice(index, 1);
|
||
// 图片赋值
|
||
this.form_images_list = list;
|
||
} catch (error) {
|
||
console.error('comment_input_img_close error:', error);
|
||
}
|
||
},
|
||
|
||
// 播放
|
||
handle_play() {
|
||
try {
|
||
this.paused = false;
|
||
this.is_manual_pause = false;
|
||
} catch (error) {
|
||
console.error('handle_play error:', error);
|
||
}
|
||
},
|
||
|
||
comment_modal_content(e) {
|
||
try {
|
||
e.stopPropagation();
|
||
} catch (error) {
|
||
console.error('comment_modal error:', error);
|
||
}
|
||
},
|
||
|
||
// 收藏
|
||
handle_like(e) {
|
||
try {
|
||
if (!app.globalData.is_single_page_check()) {
|
||
return false;
|
||
}
|
||
var user = app.globalData.get_user_info(this, 'handle_like', e);
|
||
if (user != false) {
|
||
// const id = e?.currentTarget?.dataset?.id || '';
|
||
this.set_givethumbs_num(this.current_video_id);
|
||
}
|
||
e.stopPropagation();
|
||
} catch (error) {
|
||
console.error('handle_like error:', error);
|
||
}
|
||
},
|
||
// 打开评论区
|
||
handle_comment(e) {
|
||
try {
|
||
e.stopPropagation();
|
||
// const id = this.current_video_id;
|
||
const old_data = this.video_data_list.find(item => item.id == this.current_video_id);
|
||
if (old_data && old_data.comments_list) {
|
||
// 初始化评论数据
|
||
const new_data = old_data.comments_list.map(item1 => ({
|
||
...item1,
|
||
show_sub_comment: false,
|
||
show_sub_comment_loading: false,
|
||
page: 0,
|
||
sub_comments: [],
|
||
}));
|
||
this.active_comments = new_data;
|
||
this.comments_page = 1;
|
||
this.comments_page_total = 5;
|
||
this.comment_item_loading = false;
|
||
this.show_comment_modal = true;
|
||
this.move_distance = 0;
|
||
this.is_dragging = false; // 重置拖拽状态
|
||
this.comment_start_y = 0; // 重置起始位置
|
||
this.comment_current_y = 0; // 重置当前位置
|
||
this.comment_scroll_top = 0 + Math.random(); // 滚动到最顶部
|
||
}
|
||
} catch (error) {
|
||
console.error('handle_comment error:', error);
|
||
}
|
||
},
|
||
// 关闭评论区
|
||
close_comment_modal(e) {
|
||
try {
|
||
this.active_dropdown_id = null;
|
||
this.show_comment_modal = false;
|
||
this.comment_scroll_top = 0 + Math.random(); // 关闭评论时滚动到最顶部
|
||
this.comments_reply_data = {}; // 清空回复评论数据
|
||
this.form_images_list = []; // 清空上传图片
|
||
this.comment_input_value = ''; // 清空输入框内容
|
||
this.move_distance = 0;
|
||
this.is_dragging = false; // 重置拖拽状态
|
||
this.comment_start_y = 0; // 重置起始位置
|
||
this.comment_current_y = 0; // 重置当前位置
|
||
|
||
// 清理节流定时器
|
||
if (this.comment_move_throttle_timer) {
|
||
clearTimeout(this.comment_move_throttle_timer);
|
||
this.comment_move_throttle_timer = null;
|
||
}
|
||
|
||
if (this.$refs.commentRef) {
|
||
this.$refs.commentRef.blur();
|
||
}
|
||
|
||
if (e) {
|
||
e.stopPropagation();
|
||
}
|
||
} catch (error) {
|
||
console.error('close_comment_modal error:', error);
|
||
}
|
||
},
|
||
// 评论滚动事件,记录滚动位置(带防抖)
|
||
handle_comment_scroll(e) {
|
||
try {
|
||
this.active_dropdown_id = null;
|
||
// 清除之前的防抖定时器
|
||
if (this.comment_scroll_debounce_timer) {
|
||
clearTimeout(this.comment_scroll_debounce_timer);
|
||
}
|
||
// 设置新的防抖定时器
|
||
this.comment_scroll_debounce_timer = setTimeout(() => {
|
||
this.comment_scroll_top = Math.abs(e.contentOffset.y);
|
||
}, 100); // 100ms防抖延迟
|
||
} catch (error) {
|
||
console.error('handle_comment_scroll error:', error);
|
||
}
|
||
},
|
||
// 评论滚动到底部事件
|
||
handle_comment_to_lower_scroll() {
|
||
try {
|
||
if (this.goods_bottom_line_status) {
|
||
return;
|
||
}
|
||
this.comment_item_loading = true;
|
||
// 获取数据
|
||
uni.request({
|
||
url: app.globalData.get_request_url("commentsreplylist", "index", "video"),
|
||
method: 'POST',
|
||
data: {
|
||
video_id: this.current_video_id,
|
||
page: this.comments_page + 1,
|
||
video_comments_id: 0
|
||
},
|
||
dataType: 'json',
|
||
success: res => {
|
||
const data = res.data;
|
||
if (data.code == 0) {
|
||
const new_data = data.data;
|
||
if (new_data.data.length > 0) {
|
||
// 初始化评论数据
|
||
const comment_data = new_data.data.map(item1 => ({
|
||
...item1,
|
||
show_sub_comment: false,
|
||
show_sub_comment_loading: false,
|
||
page: 0,
|
||
sub_comments: [],
|
||
}));
|
||
this.active_comments.push(...comment_data);
|
||
}
|
||
// 是否显示没有更多数据
|
||
if (new_data.page >= new_data.page_total) {
|
||
// 没有更多数据了
|
||
this.goods_bottom_line_status = true;
|
||
}
|
||
this.comments_page = new_data.page;
|
||
this.comments_page_total = new_data.page_total
|
||
}
|
||
},
|
||
complete: () => {
|
||
this.comment_item_loading = false;
|
||
}
|
||
});
|
||
} catch (error) {
|
||
console.error('handle_comment_to_lower_scroll error:', error);
|
||
}
|
||
},
|
||
// 评论拖拽开始
|
||
handle_comment_touch_start(e) {
|
||
try {
|
||
const type = e?.target?.dataset?.type || 'header';
|
||
// 如果是滚动区域内滚动到顶部才可以拖拽,如果是头部拖拽的话,一直都可以
|
||
if ((this.comment_scroll_top <= 5 && type == 'scroll') || type == 'header') {
|
||
this.comment_start_y = e?.touches[0]?.pageY || 0;
|
||
this.comment_current_y = this.comment_start_y;
|
||
this.move_distance = 0;
|
||
this.is_dragging = false; // 开始时不设置为拖拽状态,需要移动一定距离后才算拖拽
|
||
}
|
||
} catch (error) {
|
||
console.error('handle_comment_touch_start error:', error);
|
||
}
|
||
},
|
||
// 评论拖拽中
|
||
handle_comment_touch_move(e) {
|
||
try {
|
||
const type = e?.target?.dataset?.type || 'header';
|
||
// 如果是滚动区域内滚动到顶部才可以拖拽,如果是头部拖拽的话,一直都可以
|
||
if ((this.comment_scroll_top <= 5 && type == 'scroll') || type == 'header') {
|
||
// 阻止默认行为,防止页面滚动干扰
|
||
if (e.preventDefault) {
|
||
e.preventDefault();
|
||
}
|
||
|
||
const current_y = e?.touches[0]?.pageY || 0;
|
||
const move_y = current_y - this.comment_current_y;
|
||
// 小于3的时候不认为是有效滑动,避免因为手指抖动影响
|
||
if (move_y < 3) {
|
||
return;
|
||
}
|
||
const distance = current_y - this.comment_start_y;
|
||
|
||
// 只有向下移动且距离超过阈值(15px)才开始拖拽,避免误触和抖动
|
||
if (distance > 15) {
|
||
this.is_dragging = true;
|
||
this.comment_current_y = current_y;
|
||
|
||
// 使用节流控制 move_distance 的更新频率,避免计算属性频繁触发导致抖动
|
||
if (this.comment_move_throttle_timer) {
|
||
return;
|
||
}
|
||
|
||
this.move_distance = distance;
|
||
|
||
// 设置节流定时器,16ms 约等于 60fps,保证流畅度同时避免过度更新
|
||
this.comment_move_throttle_timer = setTimeout(() => {
|
||
this.comment_move_throttle_timer = null;
|
||
}, 60);
|
||
}
|
||
}
|
||
} catch(error) {
|
||
console.error('handle_comment_touch_move error:', error);
|
||
}
|
||
},
|
||
// 评论拖拽结束
|
||
handle_comment_touch_end(e) {
|
||
try {
|
||
const type = e?.target?.dataset?.type || 'header';
|
||
// 如果是滚动区域内滚动到顶部才可以拖拽,如果是头部拖拽的话,一直都可以
|
||
if ((this.comment_scroll_top <= 5 && type == 'scroll') || type == 'header') {
|
||
const move_distance = this.comment_current_y - this.comment_start_y;
|
||
// 如果拖拽距离足够大,关闭评论弹窗
|
||
if (move_distance > 150) {
|
||
this.close_comment_modal();
|
||
} else {
|
||
this.move_distance = 0;
|
||
}
|
||
this.is_dragging = false; // 拖拽结束,重置状态
|
||
|
||
// 清理节流定时器
|
||
if (this.comment_move_throttle_timer) {
|
||
clearTimeout(this.comment_move_throttle_timer);
|
||
this.comment_move_throttle_timer= null;
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.error('handle_comment_touch_end error:', error);
|
||
}
|
||
},
|
||
// 评论
|
||
send_comment() {
|
||
try {
|
||
this.active_dropdown_id = null;
|
||
let comment_text = this.comment_input_value;
|
||
if (!comment_text.trim()) return;
|
||
|
||
// video_id 视频id video_comments_id 父级评论id id 当前评论id
|
||
let new_video_comments_id = 0;
|
||
let reply_comments_id = 0
|
||
if (!isEmpty(this.comments_reply_data)) {
|
||
const { video_comments_id, id } = this.comments_reply_data;
|
||
new_video_comments_id = video_comments_id == 0 ? id : video_comments_id;
|
||
reply_comments_id = video_comments_id == 0 ? 0 : id;
|
||
}
|
||
uni.request({
|
||
url: app.globalData.get_request_url("comments", "index", "video"),
|
||
method: 'POST',
|
||
data: {
|
||
video_id: this.current_video_id,
|
||
video_comments_id: new_video_comments_id, // 如果父级评论id为0说明没有父级id,所以取当前id
|
||
reply_comments_id: reply_comments_id, // 如果父级评论id为0说明没有父级id,所以回复id为0
|
||
content: comment_text,
|
||
images: this.form_images_list.length > 0 ? (this.form_images_list[0]?.url || '') : '',
|
||
},
|
||
dataType: 'json',
|
||
success: res => {
|
||
const data = res.data;
|
||
if (data.code == 0) {
|
||
const new_data = data.data;
|
||
// 没有回复时的评论
|
||
if (new_video_comments_id == 0) {
|
||
this.active_comments.unshift({
|
||
...new_data,
|
||
show_sub_comment: false,
|
||
show_sub_comment_loading: false,
|
||
page: 0,
|
||
sub_comments: [],
|
||
})
|
||
this.video_data_list.forEach(item => {
|
||
if (item.id == this.current_video_id) {
|
||
item.comments_count++;
|
||
}
|
||
})
|
||
// this.video_data_list = this.video_data_list;
|
||
this.$set(this, 'video_data_list', this.video_data_list)
|
||
this.comment_scroll_top = 0 + Math.random(); // 添加主评论时滚动到最顶部
|
||
} else {
|
||
this.active_comments.forEach(item => {
|
||
if (item.id == new_video_comments_id) {
|
||
item.sub_comments.unshift(new_data);
|
||
item.comments_count++;
|
||
if (!item.show_sub_comment) {
|
||
item.show_sub_comment = true;
|
||
// 如果回复总数跟当前显示的数量对得上,就不显示展开. 如果之前没有页面时,设置页数和分页都为1, 否则保持之前的分页
|
||
item.page = item.comments_count == item.sub_comments.length ? (!isEmpty(item.page) && item.page > 0 ? item.page : 1) : 0;
|
||
// 如果之前没有数据时,设置总页数为1
|
||
item.page_total = !isEmpty(item.page_total) ? item.page_total : 1;
|
||
}
|
||
}
|
||
})
|
||
}
|
||
// 清空输入框,更新数据内容
|
||
this.active_comments = this.active_comments;
|
||
this.form_images_list = [];
|
||
this.comment_input_value = '';
|
||
this.comments_reply_data = {};
|
||
} else {
|
||
if (app.globalData.is_login_check(res.data)) {
|
||
app.globalData.showToast(res.data.msg);
|
||
} else {
|
||
app.globalData.showToast(t('common_sub_error_retry_tips'));
|
||
}
|
||
}
|
||
}
|
||
});
|
||
} catch (error) {
|
||
console.error('send_comment error:', error);
|
||
}
|
||
},
|
||
// 展开子评论
|
||
open_sub_comment(id, is_level) {
|
||
try {
|
||
this.active_dropdown_id = null;
|
||
const comment = this.active_comments.find(item => item.id == id);
|
||
if (comment) {
|
||
comment.show_sub_comment = true;
|
||
comment.show_sub_comment_loading = true;
|
||
// 如果是一级,并且有子评论数据,不需要调用接口,直接渲染评论信息
|
||
if (is_level == 1 && !isEmpty(comment.sub_comments)) {
|
||
comment.show_sub_comment_loading = false;
|
||
return;
|
||
}
|
||
|
||
uni.request({
|
||
url: app.globalData.get_request_url("commentsreplylist", "index", "video"),
|
||
method: 'POST',
|
||
data: {
|
||
video_id: this.current_video_id,
|
||
video_comments_id: id,
|
||
page: comment.page + 1,
|
||
},
|
||
dataType: 'json',
|
||
success: res => {
|
||
const data = res.data;
|
||
if (data.code == 0) {
|
||
const new_data = data.data;
|
||
if (comment.page == 0) {
|
||
comment.sub_comments = new_data.data;
|
||
} else if (new_data.data.length > 0) {
|
||
comment.sub_comments.push(...new_data.data);
|
||
}
|
||
comment.page = new_data.page;
|
||
comment.page_total = new_data.page_total
|
||
}
|
||
},
|
||
complete: () => {
|
||
comment.show_sub_comment_loading = false;
|
||
}
|
||
});
|
||
}
|
||
} catch (error) {
|
||
console.error('open_sub_comment error:', error);
|
||
}
|
||
},
|
||
|
||
// 收起子评论
|
||
close_sub_comment(id) {
|
||
try {
|
||
this.active_dropdown_id = null;
|
||
const comment = this.active_comments.find(item => item.id == id);
|
||
if (comment) {
|
||
comment.show_sub_comment = false;
|
||
}
|
||
} catch (error) {
|
||
console.error('close_sub_comment error:', error);
|
||
}
|
||
},
|
||
|
||
// 分享事件
|
||
handle_share() {
|
||
try {
|
||
if ((this.$refs.share || null) != null) {
|
||
this.$refs.share.init({
|
||
status: true,
|
||
share_info: this.share_info,
|
||
});
|
||
}
|
||
} catch (error) {
|
||
console.error('handle_share error:', error);
|
||
}
|
||
},
|
||
// 更新视频数据信息
|
||
get_video_data_detail(id) {
|
||
try {
|
||
uni.request({
|
||
url: app.globalData.get_request_url("data", "index", "video"),
|
||
method: 'POST',
|
||
data: {
|
||
id: id,
|
||
},
|
||
dataType: 'json',
|
||
success: res => {
|
||
const data = res.data;
|
||
if (data.code == 0) {
|
||
const new_data = data.data;
|
||
// 更新视频数据
|
||
const index = this.video_data_list.findIndex(item => item.id == id);
|
||
if (index !== -1) {
|
||
// 使用Object.assign更新原对象,保持引用不变
|
||
Object.assign(this.video_data_list[index], {
|
||
...this.video_data_list[index],
|
||
...new_data.data
|
||
});
|
||
}
|
||
}
|
||
}
|
||
});
|
||
} catch (error) {
|
||
console.error('get_video_data_detail error:', error);
|
||
}
|
||
},
|
||
|
||
// 更新点赞数量
|
||
set_givethumbs_num(id, comments_id) {
|
||
try {
|
||
uni.request({
|
||
url: app.globalData.get_request_url("givethumbs", "index", "video"),
|
||
method: 'POST',
|
||
data: {
|
||
video_id: id,
|
||
...(isEmpty(comments_id) ? {} : {video_comments_id: comments_id}),
|
||
},
|
||
dataType: 'json',
|
||
success: res => {
|
||
const data = res.data;
|
||
if (data.code == 0) {
|
||
const new_data = data.data;
|
||
|
||
// 提取更新点赞状态的公共函数
|
||
const updateThumbsStatus = (target, new_data) => {
|
||
target.give_thumbs_count = new_data.count;
|
||
target.is_give_thumbs = new_data.is_active;
|
||
};
|
||
|
||
// 优化后的遍历逻辑
|
||
for (let i = 0; i < this.video_data_list.length; i++) {
|
||
const item = this.video_data_list[i];
|
||
if (item.id == id) {
|
||
if (!isEmpty(comments_id)) {
|
||
// 安全检查comments数组是否存在
|
||
if (this.active_comments && Array.isArray(this.active_comments)) {
|
||
for (let j = 0; j < this.active_comments.length; j++) {
|
||
const comment = this.active_comments[j];
|
||
if (comment.id == comments_id) {
|
||
updateThumbsStatus(comment, new_data);
|
||
break; // 处理完当前item后跳出循环
|
||
} else {
|
||
// 安全检查sub_comments数组是否存在
|
||
if (comment.sub_comments && Array.isArray(comment.sub_comments)) {
|
||
for (let k = 0; k < comment.sub_comments.length; k++) {
|
||
const sub_comment = comment.sub_comments[k];
|
||
|
||
if (sub_comment.id == comments_id) {
|
||
updateThumbsStatus(sub_comment, new_data);
|
||
break; // 处理完当前item后跳出循环
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
this.video_data_list[i].comments_list = this.active_comments;
|
||
} else {
|
||
updateThumbsStatus(item, new_data);
|
||
}
|
||
break; // 处理完当前item后跳出外层循环
|
||
}
|
||
}
|
||
|
||
// this.video_data_list = this.video_data_list;
|
||
this.$set(this, 'video_data_list', this.video_data_list)
|
||
} else {
|
||
if (app.globalData.is_login_check(res.data)) {
|
||
app.globalData.showToast(res.data.msg);
|
||
} else {
|
||
app.globalData.showToast(t('common_sub_error_retry_tips'));
|
||
}
|
||
}
|
||
}
|
||
});
|
||
} catch (error) {
|
||
console.error('set_givethumbs_num error:', error);
|
||
}
|
||
},
|
||
// 主评论回复
|
||
comment_reply(comments) {
|
||
try {
|
||
this.active_dropdown_id = null;
|
||
if (!isEmpty(comments)) {
|
||
this.comments_reply_data = comments;
|
||
}
|
||
} catch (error) {
|
||
console.error('comment_reply error:', error);
|
||
}
|
||
},
|
||
// 删除回复评论数据
|
||
comment_data_delete() {
|
||
try {
|
||
this.active_dropdown_id = null;
|
||
this.comments_reply_data = {};
|
||
} catch (error) {
|
||
console.error('comment_data_delete error:', error);
|
||
}
|
||
},
|
||
// 播放进度变化时触发
|
||
handle_time_update(e) {
|
||
try {
|
||
if (this.is_seeking) return;
|
||
let duration = this.current_video_duration;
|
||
// #ifdef MP-ALIPAY
|
||
if (e.detail.videoDuration > 0) {
|
||
duration = e.detail.videoDuration;
|
||
}
|
||
// #endif
|
||
// #ifndef MP-ALIPAY
|
||
if (e.detail.duration > 0) {
|
||
duration = e.detail.duration;
|
||
}
|
||
// #endif
|
||
|
||
this.$set(this, 'current_video_duration', duration);
|
||
this.$set(this, 'current_video_progress', e.detail.currentTime)
|
||
} catch (error) {
|
||
console.error('handle_time_update error:', error);
|
||
}
|
||
},
|
||
// 视频进度条拖动时触发事件
|
||
handle_slider_changing() {
|
||
try {
|
||
this.is_seeking = true;
|
||
e.stopPropagation();
|
||
} catch (error) {
|
||
console.error('handle_slider_changing error:', error);
|
||
}
|
||
},
|
||
// 评论点赞
|
||
comment_like(id) {
|
||
try {
|
||
this.active_dropdown_id = null;
|
||
this.set_givethumbs_num(this.current_video_id, id);
|
||
} catch (error) {
|
||
console.error('comment_like error:', error);
|
||
}
|
||
},
|
||
// 视频进度条拖动完成触发事件
|
||
handle_slider_change(e) {
|
||
try {
|
||
const seek_time = e.detail.value;
|
||
if (this.create_video_contexts && this.create_video_contexts[this.current_index]) {
|
||
this.create_video_contexts[this.current_index].seek(seek_time);
|
||
this.current_video_progress = seek_time;
|
||
}
|
||
setTimeout(() => {
|
||
this.is_seeking = false;
|
||
}, 100);
|
||
// e.stopPropagation();
|
||
} catch (error) {
|
||
console.error('handle_slider_change error:', error);
|
||
}
|
||
},
|
||
// 视频进度条时间显示
|
||
format_time(seconds) {
|
||
try {
|
||
if (isNaN(seconds) || seconds < 0) {
|
||
return '00:00';
|
||
}
|
||
const min = Math.floor(seconds / 60);
|
||
const sec = Math.floor(seconds % 60);
|
||
return `${min < 10 ? '0' : ''}${min}:${sec < 10 ? '0' : ''}${sec}`;
|
||
} catch (error) {
|
||
console.error('format_time error:', error);
|
||
}
|
||
},
|
||
// 返回上一页
|
||
handle_back(e) {
|
||
try {
|
||
app.globalData.page_back_prev_event();
|
||
e.stopPropagation();
|
||
} catch (error) {
|
||
console.error('handle_back error:', error);
|
||
}
|
||
},
|
||
// 跳转搜索记录页面
|
||
handle_search() {
|
||
try {
|
||
// 跳转到搜索记录页面
|
||
app.globalData.url_open(`/pages/plugins/video/search-record/search-record`, false);
|
||
} catch (error) {
|
||
console.error('handle_search error:', error);
|
||
}
|
||
},
|
||
// 关闭推荐商品
|
||
product_close_event(e) {
|
||
try {
|
||
this.video_data_list.forEach((item) => {
|
||
if (item.id == this.current_video_id) {
|
||
item.show_goods = false;
|
||
}
|
||
});
|
||
// this.video_data_list = this.video_data_list;
|
||
this.$set(this, 'video_data_list', this.video_data_list);
|
||
e.stopPropagation();
|
||
} catch (error) {
|
||
console.error('product_close_event error:', error);
|
||
}
|
||
},
|
||
// 点击商品卡片触发事件
|
||
handle_product_card_item(e) {
|
||
try {
|
||
const id = e?.currentTarget?.dataset?.id || '';
|
||
const data = this.video_data_list.find(item => item.id == id);
|
||
if (!isEmpty(data) && !isEmpty(data.goods)) {
|
||
app.globalData.url_open(data.goods.goods_url);
|
||
}
|
||
e.stopPropagation();
|
||
} catch (error) {
|
||
console.error('handle_product_card_item error:', error);
|
||
}
|
||
},
|
||
// 点击购买商品按钮触发事件
|
||
handle_product_button(e) {
|
||
try {
|
||
const id = e.currentTarget.dataset.id;
|
||
this.video_data_list.forEach((item, index) => {
|
||
if (item.id == id) {
|
||
if (item.show_goods && !isEmpty(item.goods)) {
|
||
app.globalData.url_open(item.goods.goods_url);
|
||
} else {
|
||
item.show_goods = true;
|
||
}
|
||
}
|
||
});
|
||
|
||
// this.video_data_list = this.video_data_list;
|
||
this.$set(this, 'video_data_list', this.video_data_list);
|
||
e.stopPropagation();
|
||
} catch (error) {
|
||
console.error('handle_product_button error:', error);
|
||
}
|
||
},
|
||
// 清理所有视频资源
|
||
cleanup_all_videos() {
|
||
try {
|
||
// 暂停所有视频
|
||
this.pause_all_videos_except(-1);
|
||
} catch (error) {
|
||
console.error('清理视频资源时出错:', error);
|
||
}
|
||
},
|
||
// 处理下拉菜单切换
|
||
handle_toggle_dropdown(comment_id) {
|
||
try {
|
||
if (this.active_dropdown_id == comment_id) {
|
||
this.active_dropdown_id = null;
|
||
} else {
|
||
this.active_dropdown_id = comment_id;
|
||
}
|
||
} catch (error) {
|
||
console.error('handle_toggle_dropdown error:', error);
|
||
}
|
||
},
|
||
|
||
// 关闭下拉菜单
|
||
handle_dropdown_item_click(comment_id, obj) {
|
||
try {
|
||
if (this.active_dropdown_id == comment_id) {
|
||
this.active_dropdown_id = null;
|
||
}
|
||
// 处理不同操作
|
||
if (obj.type == 'delete') {
|
||
// 确认删除
|
||
uni.showModal({
|
||
title: t('common_warm_tips'),
|
||
content: t('common_delete_confirm_tips'),
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
// 调用删除接口
|
||
this.delete_comment(comment_id);
|
||
}
|
||
}
|
||
});
|
||
} else if (obj.type == 'report') {
|
||
// 举报评论
|
||
this.$refs.popupReportRef.open();
|
||
this.report_comment_id = comment_id;
|
||
}
|
||
} catch (error) {
|
||
console.error('handle_dropdown_item_click error:', error);
|
||
}
|
||
},
|
||
// 删除评论
|
||
delete_comment(comment_id) {
|
||
try {
|
||
uni.request({
|
||
url: app.globalData.get_request_url("delete", "index", "video"),
|
||
method: 'POST',
|
||
data: {
|
||
ids: comment_id,
|
||
},
|
||
dataType: 'json',
|
||
success: res => {
|
||
if (res.data.code == 0) {
|
||
// 删除评论数据
|
||
this.delete_comment_handle(comment_id);
|
||
// 显示删除成功提示
|
||
app.globalData.showToast(res.data.msg, 'success');
|
||
} else {
|
||
if (app.globalData.is_login_check(res.data)) {
|
||
app.globalData.showToast(res.data.msg);
|
||
} else {
|
||
app.globalData.showToast(t('common_sub_error_retry_tips'));
|
||
}
|
||
}
|
||
}
|
||
});
|
||
} catch (error) {
|
||
console.error('send_comment error:', error);
|
||
}
|
||
},
|
||
// 删除评论数据处理
|
||
delete_comment_handle(comment_id) {
|
||
try {
|
||
// 删除成功,从active_comments中移除对应数据
|
||
if (this.active_comments && Array.isArray(this.active_comments)) {
|
||
// 创建新的数组来存储过滤后的结果
|
||
const filteredComments = [];
|
||
for (let i = 0; i < this.active_comments.length; i++) {
|
||
const comment = this.active_comments[i];
|
||
|
||
// 清空回复评论数据(仅当匹配时)
|
||
if (comment.id === this.comments_reply_data.id || (comment.sub_comments && Array.isArray(comment.sub_comments) && comment.sub_comments.some(subComment => subComment.id === this.comments_reply_data.id))) {
|
||
this.comments_reply_data = {};
|
||
}
|
||
|
||
// 如果是父级评论且 id 匹配,跳过整个评论(包括子评论)
|
||
if (comment.id === comment_id) {
|
||
continue;
|
||
}
|
||
|
||
// 处理子评论
|
||
if (comment.sub_comments && Array.isArray(comment.sub_comments)) {
|
||
// 查找并移除匹配的子评论
|
||
const targetSubCommentIndex = comment.sub_comments.findIndex(subComment => subComment.id === comment_id);
|
||
if (targetSubCommentIndex !== -1) {
|
||
// 移除目标子评论
|
||
comment.sub_comments.splice(targetSubCommentIndex, 1);
|
||
// 更新显示状态和评论数
|
||
if (comment.sub_comments.length === 0) {
|
||
comment.show_sub_comment = false;
|
||
}
|
||
comment.comments_count -= 1;
|
||
}
|
||
}
|
||
|
||
// 保留当前评论
|
||
filteredComments.push(comment);
|
||
}
|
||
// 删除之后更新评论数据
|
||
this.video_data_list.forEach(item => {
|
||
if (item.id == this.current_video_id) {
|
||
item.comments_count = filteredComments.length;
|
||
}
|
||
})
|
||
// 更新数据
|
||
this.active_comments = filteredComments;
|
||
// this.video_data_list = this.video_data_list;
|
||
this.$set(this, 'video_data_list', this.video_data_list)
|
||
}
|
||
} catch (error) {
|
||
console.error('delete_comment_handle error:', error);
|
||
}
|
||
},
|
||
// 关闭举报弹窗
|
||
popup_report_close_event() {
|
||
try {
|
||
// this.$refs.popupReportRef.close();
|
||
this.current_main_index = 0;
|
||
this.current_sub_index = 0;
|
||
} catch (error) {
|
||
console.error('popup_report_close_event error:', error);
|
||
}
|
||
},
|
||
|
||
// 直接选择主原因(用于一行显示的点击)
|
||
select_main_reason(e) {
|
||
try {
|
||
const index = e?.detail?.value || 0;
|
||
const main_index = parseInt(index);
|
||
this.current_main_index = main_index;
|
||
this.current_sub_index = 0; // 默认选中第一个子类型
|
||
} catch (error) {
|
||
console.error('select_main_reason error:', error);
|
||
}
|
||
},
|
||
|
||
// 直接选择子类型(用于一行显示的点击)
|
||
select_sub_reason(e) {
|
||
try {
|
||
const index = e?.detail?.value || 0;
|
||
const sub_index = parseInt(index);
|
||
this.current_sub_index = sub_index;
|
||
} catch (error) {
|
||
console.error('select_sub_reason error:', error);
|
||
}
|
||
},
|
||
/*
|
||
* 提交举报
|
||
*/
|
||
submit_report() {
|
||
try {
|
||
// 获取选中的举报原因和具体类型
|
||
const main_reason = this.report_type_list[this.current_main_index] || {};
|
||
const sub_reason = main_reason?.data[this.current_sub_index] || '';
|
||
// 调用举报接口
|
||
uni.request({
|
||
url: app.globalData.get_request_url("report", "index", "video"),
|
||
method: 'POST',
|
||
data: {
|
||
id: this.report_comment_id,
|
||
reason: main_reason?.name || '',
|
||
type: sub_reason
|
||
},
|
||
dataType: 'json',
|
||
success: res => {
|
||
if (res.data.code == 0) {
|
||
// 显示删除成功提示
|
||
app.globalData.showToast(res.data.msg, 'success');
|
||
// 关闭弹窗
|
||
this.popup_report_close_event();
|
||
} else {
|
||
if (app.globalData.is_login_check(res.data)) {
|
||
app.globalData.showToast(res.data.msg);
|
||
} else {
|
||
app.globalData.showToast(t('common_sub_error_retry_tips'));
|
||
}
|
||
}
|
||
}
|
||
});
|
||
} catch (error) {
|
||
console.error('submit_report error:', error);
|
||
}
|
||
},
|
||
// 键盘显示时,切换输入框
|
||
add_comment() {
|
||
try {
|
||
//#ifndef H5
|
||
this.active_dropdown_id = null;
|
||
this.handle_comment_input_value();
|
||
this.active_dropdown_id = null;
|
||
//#endif
|
||
} catch (error) {
|
||
console.error('add_comment error:', error);
|
||
}
|
||
},
|
||
/**
|
||
* 键盘高度变化监听处理
|
||
* @param {Object} res - 键盘高度变化事件对象
|
||
*/
|
||
listener(res) {
|
||
try {
|
||
if (res.height > 0) {
|
||
this.listener_height = res.height - 1;
|
||
} else {
|
||
this.listener_height = 0;
|
||
}
|
||
} catch (error) {
|
||
console.error('listener error:', error);
|
||
}
|
||
},
|
||
/**
|
||
* 绑定键盘高度变化监听事件
|
||
*/
|
||
bind_keyboard_listener() {
|
||
try {
|
||
uni.onKeyboardHeightChange(this.listener);
|
||
} catch (error) {
|
||
console.error('bind_keyboard_listener error:', error);
|
||
}
|
||
},
|
||
/**
|
||
* 解绑键盘高度变化监听事件
|
||
*/
|
||
unbind_keyboard_listener() {
|
||
try {
|
||
uni.offKeyboardHeightChange(this.listener);
|
||
} catch (error) {
|
||
console.error('unbind_keyboard_listener error:', error);
|
||
}
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
<style lang="scss" scoped>
|
||
@import './detail-nvue.css';
|
||
</style> |