Files
huangjingfen/pro_v3.5.1/view/uniapp_v2/pages/index/components/community.vue
apple 8e17762510 feat(uniapp_v2): 二开功能迁移与小程序主包优化
- 从 uniapp 迁移 HJF 页面、API、组件及用户/订单相关改动
- queue、assets 使用独立分包以降低主包体积
- 修复首页单根节点与支付结果页 v-if 链
- 关闭 HjfDemoPanel 全局注册;uniNoticeBar 注释 $getAppWebview 避免 __webviewId__ 报错
- 配置域名与 manifest 应用名称;cache/store 防御性处理

Made-with: Cursor
2026-03-26 12:16:01 +08:00

533 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view :style="[shortVideoWrapStyle]" v-if="videoList.length && !dataConfig.isHide">
<view class="shortVideo" :style="[shortVideoStyle]">
<view class="nav acea-row row-between-wrapper" :style="[navStyle]">
<view v-if="dataConfig.titleConfig.tabVal" class="title" :style="[titleStyle]">{{ dataConfig.titleTxtConfig.value }}</view>
<easy-loadimage v-else
:image-src="dataConfig.imgConfig.url"
width="134rpx"
height="34rpx"></easy-loadimage>
<view class="more" :style="[buttonStyle]" @click="more(0)">
{{ dataConfig.rightBntConfig.value }}
<text class="iconfont icon-ic_rightarrow" :style="[buttonStyle]"></text>
</view>
<image class="clover" src="/static/img/clover.png" mode=""></image>
</view>
<view v-if="dataConfig.styleConfig.tabVal == 0" class="list" :style="[listStyle]">
<scroll-view scroll-x="true" class="scroll white-nowrap pl-20" show-scrollbar="false">
<view class="item inline-block"
v-for="item in videoList" :key="item.id"
@click="more(item.id,item.content_type)"
:style="[itemStyle]">
<view class="relative">
<easy-loadimage
:image-src="item.image"
width="296rpx"
height="369rpx"
:borderRadius="imageRadius"></easy-loadimage>
<view class="abs-lb w-full text--w111-fff z-80">
<view class="fs-24 pl-16 lh-38rpx w-full line1" v-show="item.title">{{item.title}}</view>
<view class="pl-16 pb-14 flex-y-center">
<image class="w-36 h-36 rd-50-p111-" :src="item.author_image"></image>
<text class="pl-8 fs-20">{{item.author}}</text>
</view>
</view>
<view class="copty-mask" :style="{'border-radius': imageRadius}"></view>
</view>
</view>
</scroll-view>
</view>
<view v-else class="p-20" :style="[listStyle]">
<view :class="'wf-page wf-page'+type">
<!-- left -->
<view>
<view id="left" v-if="leftList.length">
<view v-for="(item,index) in leftList" :key="index"
class="wf-item" :style="[wfItemStyle]"
@click="more(item.id,item.content_type)">
<view class="wf-item-page wf-page0">
<view class='pictrue overflow-picture relative'>
<easy-loadimage
mode="widthFix"
:image-src="item.image"
width="100%"
:borderRadius="imageRadius"></easy-loadimage>
<view class="player flex-center" v-if="item.content_type == 2">
<text class="iconfont icon-ic_right2 fs-20"></text>
</view>
<view class="w-60 h-36 rd-4rpx flex-center fs-22 text--w111-fff pic-number"
v-if="item.content_type == 1">{{item.slider_image.length}}</view>
<view class="abs-lt w-full h-full flex-col flex-center text--w111-fff shenhe"
v-if="[0,-1].includes(item.is_verify)">
<text class="fs-28" v-show="item.is_verify == 0">正在审核</text>
<text class="fs-24 pt-22" v-show="item.is_verify == 0">通过后将展示在列表</text>
<text class="fs-28" v-show="item.is_verify == -1">审核未通过</text>
<text class="fs-24 pt-22" v-show="item.is_verify == -1">查看未通过原因</text>
</view>
</view>
<view class="info_box box-border">
<view class="w-full lh-40rpx fs-28 line2">{{item.title}}</view>
<view class="pt-22 fs-22 text--w111-999 flex-between-center">
<view class="flex-y-center" @tap.stop="toUser">
<image class="w-34 h-34 rd-50-p111-" :src="item.author_image"></image>
<text class="pl-8">{{item.author}}</text>
</view>
<view class="flex-y-center" :class="{'text-red': item.is_like}" @tap.stop="contentLike(item)">
<text class="iconfont fs-22" :class="item.is_like ? 'icon-icon_Like_2' : 'icon-ic_Like'"></text>
<text class="pl-10">{{item.like_num}}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- right -->
<view>
<view id="right" v-if="rightList.length">
<view v-for="(item,index) in rightList" :key="index"
class="wf-item" :style="[wfItemStyle]"
@click="more(item.id,item.content_type)">
<view class="wf-item-page wf-page0">
<view class='pictrue overflow-picture relative'>
<easy-loadimage
mode="widthFix"
:image-src="item.image"
width="100%"
:borderRadius="imageRadius"></easy-loadimage>
<view class="player flex-center" v-if="item.content_type == 2">
<text class="iconfont icon-ic_right2 fs-20"></text>
</view>
<view class="w-60 h-36 rd-4rpx flex-center fs-22 text--w111-fff pic-number"
v-if="item.content_type == 1">{{item.slider_image.length}}</view>
<view class="abs-lt w-full h-full flex-col flex-center text--w111-fff shenhe"
v-if="[0,-1].includes(item.is_verify)">
<text class="fs-28" v-show="item.is_verify == 0">正在审核</text>
<text class="fs-24 pt-22" v-show="item.is_verify == 0">通过后将展示在列表</text>
<text class="fs-28" v-show="item.is_verify == -1">审核未通过</text>
<text class="fs-24 pt-22" v-show="item.is_verify == -1">查看未通过原因</text>
</view>
</view>
<view class="info_box box-border">
<view class="w-full lh-40rpx fs-28 line2">{{item.title}}</view>
<view class="pt-22 fs-22 text--w111-999 flex-between-center">
<view class="flex-y-center" @tap.stop="toUser">
<image class="w-34 h-34 rd-50-p111-" :src="item.author_image"></image>
<text class="pl-8">{{item.author}}</text>
</view>
<view class="flex-y-center" :class="{'text-red': item.is_like}" @tap.stop="contentLike(item)">
<text class="iconfont fs-22" :class="item.is_like ? 'icon-icon_Like_2' : 'icon-ic_Like'"></text>
<text class="pl-10">{{item.like_num}}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { communityListApi, getCommunityConfig, communityLikeApi } from "@/api/community.js";
import { HTTP_REQUEST_URL } from '@/config/app';
import {LOGIN_STATUS} from '@/config/cache';
import { mapGetters } from 'vuex'
export default {
name: 'community',
props: {
dataConfig: {
type: Object,
default: () => {}
},
isSortType: {
type: String | Number,
default: 0
}
},
data() {
return {
videoList: [],
bgColor: '',
infoColor: '',
mbCongfig: 0,
prConfig: 0, //背景边距
numConfig: 0,
allList: [], // 全部列表
leftList: [], // 左边列表
rightList: [], // 右边列表
mark: 0, // 列表标记
boxHeight: [], // 下标0和1分别为左列和右列高度
type:0,
updateNum:10,
}
},
computed: {
...mapGetters(['isLogin','uid']),
navStyle() {
return {
'border-radius':`${this.dataConfig.fillet.valList[0].val * 2}rpx ${this.dataConfig.fillet.valList[1].val * 2}rpx ${this.dataConfig.fillet.valList[3].val * 2}rpx ${this.dataConfig.fillet.valList[2].val * 2}rpx`,
'background': `linear-gradient(90deg, ${this.dataConfig.headerBgColor.color[0].item} 0%, ${this.dataConfig.headerBgColor.color[1].item} 100%)`,
};
},
titleStyle() {
let fontStyle = 'normal';
let fontWeight = 'normal';
switch (this.dataConfig.titleText.tabVal) {
case 0:
fontWeight = 'bold'
break;
case 2:
fontStyle = 'italic'
fontWeight = 'bold'
break;
}
return {
'font-style': this.dataConfig.titleText.tabVal == 2 ? 'italic' : '',
'font-size': `${this.dataConfig.titleNumber.val * 2}rpx`,
'font-weight': this.dataConfig.titleText.tabVal == 0 ? 'bold' : '',
color: this.dataConfig.titleColor.color[0].item
};
},
buttonStyle() {
return {
'font-size': `${this.dataConfig.bntNumber.val * 2}rpx`,
'color': this.dataConfig.headerBntColor.color[0].item,
};
},
itemStyle() {
let marginTop = 0;
let marginLeft = 0;
let marginRight = 0;
if (this.dataConfig.styleConfig.tabVal == 0) {
// marginLeft = `${this.dataConfig.videoSpace2.val * 2}rpx`;
marginRight = `${this.dataConfig.videoSpace2.val * 2}rpx`;
} else {
marginTop = `${this.dataConfig.videoSpace.val * 2}rpx`;
}
return {
'margin-top': marginTop,
'margin-right': marginRight,
};
},
itemLastStyle() {
let marginRight = 0;
if (this.dataConfig.styleConfig.tabVal) {
marginRight = `${this.dataConfig.videoSpace2.val * 2}rpx`;
}
return {
'margin-right': marginRight,
};
},
imageRadius() {
let borderRadius = [`${this.dataConfig.filletImg.val * 2}rpx`];
if (this.dataConfig.filletImg.type) {
borderRadius = [];
for (let i = 0; i < this.dataConfig.filletImg.valList.length; i++) {
borderRadius.push(`${this.dataConfig.filletImg.valList[i].val * 2}rpx`);
}
}
return borderRadius.join(' ');
},
shortVideoWrapStyle(){
return {
padding: `${this.dataConfig.topConfig.val * 2}rpx ${this.dataConfig.prConfig.val * 2}rpx ${this.dataConfig.bottomConfig.val * 2}rpx`,
marginTop: `${this.dataConfig.mbConfig.val * 2}rpx`,
background: this.dataConfig.bottomBgColor.color[0].item,
}
},
shortVideoStyle() {
let borderRadius = `${this.dataConfig.fillet.val * 2}rpx`;
if (this.dataConfig.fillet.type) {
borderRadius =
`${this.dataConfig.fillet.valList[0].val * 2}rpx ${this.dataConfig.fillet.valList[1].val * 2}rpx ${this.dataConfig.fillet.valList[3].val * 2}rpx ${this.dataConfig.fillet.valList[2].val * 2}rpx`;
}
return {
borderRadius,
}
},
listStyle() {
return {
'background': `linear-gradient(90deg, ${this.dataConfig.moduleColor.color[0].item} 0%, ${this.dataConfig.moduleColor.color[1].item} 100%)`,
};
},
wfItemStyle(){
let windowWidth = uni.getWindowInfo().windowWidth;
return {
width: (windowWidth - 30 - (this.dataConfig.prConfig.val * 2))/2 + 'px'
}
},
activeValue(){
return this.dataConfig.selectConfig.activeValue || ''
}
},
watch:{
// 监听列表数据变化
videoList: {
handler(nVal,oVal){
// 如果数据为空或新的列表数据少于旧的列表数据(通常为下拉刷新或切换排序或使用筛选器),初始化变量
if (!this.videoList.length ||
(this.videoList.length === this.updateNum && this.videoList.length <= this.allList.length)) {
this.allList = [];
this.leftList = [];
this.rightList = [];
this.boxHeight = [];
this.mark = 0;
}
// 如果列表有值调用waterfall方法
if (this.videoList.length) {
this.allList = this.videoList;
this.leftList = [];
this.rightList = [];
this.boxHeight = [];
this.allList.forEach((v, i) => {
if(this.allList.length < 3 || (this.allList.length <= 7 && this.allList.length - i > 1) || (this.allList.length > 7 && this.allList.length - i > 2)) {
if(i % 2){
this.rightList.push(v);
}else{
this.leftList.push(v);
}
}
});
if(this.allList.length < 3){
this.mark = this.allList.length+1;
}else if(this.allList.length <= 7){
this.mark = this.allList.length - 1;
}else{
this.mark = this.allList.length - 2;
}
if(this.mark < this.allList.length){
this.waterFall()
}
}
},
immediate: true,
deep:true
},
// 监听标记当标记发生变化则执行下一个item排序
mark() {
const len = this.allList.length;
if (this.mark < len && this.mark !== 0 && this.boxHeight.length) {
this.waterFall();
}
}
},
mounted() {
getCommunityConfig().then(res=>{
if(res.data.community_status == 1){
this.getVideoList();
}
})
},
methods: {
contentLike(item){
if(!this.isLogin) return this.$util.Tips({
title: '请登录'
});
let status = item.is_like == 1 ? 0 : 1;
let that = this;
communityLikeApi(item.id,{status}).then(res=>{
item.is_like = item.is_like == 1 ? 0 : 1
}).catch(err=>{
return this.$util.Tips({
title: err
});
})
},
// 瀑布流排序
waterFall() {
const i = this.mark;
if (i == 0) {
// 初始化,从左边开始插入
this.leftList.push(this.allList[i]);
// 更新左边列表高度
this.getViewHeight(0);
} else if (i == 1) {
// 第二个item插入默认为右边插入
this.rightList.push(this.allList[i]);
// 更新右边列表高度
this.getViewHeight(1);
} else {
// 根据左右列表高度判断下一个item应该插入哪边
if(!this.boxHeight.length){
this.rightList.length < this.leftList.length
? this.rightList.push(this.allList[i])
: this.leftList.push(this.allList[i]);
} else {
const leftOrRight = this.boxHeight[0] > this.boxHeight[1] ? 1 : 0;
if (leftOrRight) {
this.rightList.push(this.allList[i])
} else {
this.leftList.push(this.allList[i])
}
}
// 更新插入列表高度
this.getViewHeight();
}
},
// 获取列表高度
getViewHeight() {
// 使用nextTick确保页面更新结束后再请求高度
this.$nextTick(() => {
setTimeout(()=>{
uni.createSelectorQuery().in(this).select('#right').boundingClientRect(res => {
res ? this.boxHeight[1] = res.height : '';
uni.createSelectorQuery().in(this).select('#left').boundingClientRect(res => {
res ? this.boxHeight[0] = res.height : '';
this.mark = this.mark + 1;
}).exec();
}).exec();
},100)
})
},
// item点击
itemTap(item) {
if(item.content_type == 1){
uni.navigateTo({
url: '/pages/discover/discoverDetails/index?id=' + item.id
})
}else{
uni.navigateTo({
url: '/pages/discover/discoverVideo/index?id=' + item.id
})
}
},
getVideoList: function() {
let that = this;
communityListApi({
page: 1,
limit: this.dataConfig.numberConfig.val,
topic_id: this.activeValue
}).then(res => {
that.videoList = res.data;
});
},
more(id,type) {
if(id == 0){
uni.reLaunch({
url: '/pages/discoverIndex/index'
})
}else{
if(type == 1){
uni.navigateTo({
url: '/pages/discover/discoverDetails/index?id=' + id
})
}else{
// #ifdef H5 || MP-WEIXIN
uni.navigateTo({
url: '/pages/discover/discoverVideo/index?id=' + id
})
// #endif
// #ifdef APP-PLUS
let href = encodeURIComponent(`${HTTP_REQUEST_URL}/pages/discover/discoverVideo/index?content_type=2&id=${id}&token=${this.$Cache.get(LOGIN_STATUS)}`)
uni.navigateTo({
url: `/pages/discover/discoverVideo/app?url=${href}`
})
// #endif
}
}
},
}
}
</script>
<style lang="scss">
.shortVideo {
overflow: hidden;
.nav {
width: 100%;
padding: 0 24rpx;
height: 96rpx;
background: linear-gradient(270deg, #FFFFFF 0%, #FFFFFF 100%);
position: relative;
.clover{
position: absolute;
right: 190rpx;
top: 20rpx;
width: 100rpx;
height: 100rpx;
}
.more {
font-size: 24rpx;
color: #999999;
.iconfont {
font-size: 24rpx;
}
}
}
.list {
padding: 24rpx 0;
border-radius: 0rpx 0rpx 16rpx 16rpx;
background: #FFFFFF;
}
}
.wf-page {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 20rpx;
}
.wf-item {
padding-bottom: 20rpx;
}
.wf-page1 .wf-item{
margin-top: 20rpx;
background-color: #fff;
border-radius: 20rpx;
padding-bottom: 0;
}
.overflow-picture{
max-height: 500rpx;
overflow-y: hidden;
}
.info_box{
padding: 24rpx 0;
border-radius: 0 0 24rpx 24rpx;
}
.box-border{
// border: 1rpx solid #eee;
}
.text-red{
color: #e93323;
}
.player{
position: absolute;
top: 20rpx;
right: 20rpx;
width: 40rpx;
height: 40rpx;
border-radius: 50%;
background-color: rgba(51, 51, 51, 0.5);
color: #fff;
}
.shenhe{
background-color: rgba(0,0,0,0.4);
}
.pic-number{
position: absolute;
right: 16rpx;
bottom: 16rpx;
background: rgba(102, 102, 102, 0.50);
}
.copty-mask{
position: absolute;
left: 0;
top: 0;
width: 296rpx;
height: 369rpx;
background: linear-gradient( 180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.4) 100%);
z-index: 20;
}
</style>