feat:我的动态;我的评价;访客记录;朋友圈操作;上传相册;我的相册;列表和导航按钮调整;朋友圈卡片;用户卡片;查询朋友圈详情;关注公众号帘幕
This commit is contained in:
1 parent
7bc0b920f6
commit
1f4a52807c
27 files changed
+873
-683
No files matched your search
@@ -164,6 +164,27 @@
|
||||
"navigationBarTitleText": "喜欢",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "my-moment",
|
||||
"style": {
|
||||
"navigationBarTitleText": "我的动态",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "view-record",
|
||||
"style": {
|
||||
"navigationBarTitleText": "访客记录",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "upload-album",
|
||||
"style": {
|
||||
"navigationBarTitleText": "上传照片",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
</view>
|
||||
|
||||
<wd-index-bar sticky>
|
||||
<view v-for="(item, index) in cityIndex" :key="index">
|
||||
<view v-for="(item, index) in useCityIndex()" :key="index">
|
||||
<wd-index-anchor :index="item.letter" />
|
||||
<wd-cell
|
||||
border
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getCurrentInstance } from 'vue';
|
||||
import cityIndex, { type cityItem } from './city-index';
|
||||
import useCityIndex, { type cityItem } from '@/sheep/hooks/use-city-index';
|
||||
// @ts-ignore
|
||||
import sheep from '@/sheep';
|
||||
|
||||
@@ -56,13 +56,13 @@
|
||||
const selectHot = (v: cityItem) => {
|
||||
sheep.$store('user').setUserCity(v);
|
||||
eventChannel.emit('changeCity');
|
||||
uni.navigateBack();
|
||||
back();
|
||||
};
|
||||
|
||||
const select = (v: cityItem) => {
|
||||
sheep.$store('user').setUserCity(v);
|
||||
eventChannel.emit('changeCity');
|
||||
uni.navigateBack();
|
||||
back();
|
||||
};
|
||||
|
||||
function back() {
|
||||
|
||||
+30
-43
@@ -22,16 +22,11 @@
|
||||
</template>
|
||||
</wd-navbar>
|
||||
|
||||
<scroll-view
|
||||
style="height: calc(100vh - 88px)"
|
||||
scroll-y
|
||||
refresher-enabled
|
||||
refresher-background="#222"
|
||||
:refresher-triggered="refresherTriggered"
|
||||
:refresher-threshold="100"
|
||||
@refresherrefresh="onRefresherRefresh"
|
||||
@refresherabort="onRefresherAbort"
|
||||
@scrolltolower="onScrollToLower"
|
||||
<scroll-list
|
||||
style="height: calc(100dvh - 88px)"
|
||||
:loadMoreStatus="loadMoreStatus"
|
||||
@refresh="refreshList"
|
||||
@loadMore="listLoadMore"
|
||||
@scroll="onScroll"
|
||||
>
|
||||
<view class="w-full h-500rpx relative">
|
||||
@@ -110,26 +105,16 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<moment
|
||||
v-for="item in listData"
|
||||
:avatar="item.member?.memberAvatar"
|
||||
:name="item.member?.memberNickname"
|
||||
:verification="item.verification"
|
||||
:info="`未知性别 · ${item.member?.memberAge}岁 | ${item.member?.memberOcc}`"
|
||||
:content="item.description"
|
||||
:images="[item.coverPic]"
|
||||
:location="item.issueAddress"
|
||||
:likes="item.likes"
|
||||
:comments="item.comments"
|
||||
/>
|
||||
|
||||
<uni-load-more
|
||||
:status="loadMoreStatus"
|
||||
:content-text="loadMoreContent"
|
||||
@clickLoadMore="onClickLoadMore"
|
||||
/>
|
||||
<view style="height: 100rpx"></view>
|
||||
</scroll-view>
|
||||
<moment-card v-if="listData.length" v-for="item in listData" :data="item" />
|
||||
<view v-else class="flex px-4 py-4">
|
||||
<wd-skeleton :row-col="[{ size: '50px', type: 'circle' }]" animation="flashed" />
|
||||
<wd-skeleton
|
||||
:custom-style="{ width: '100%', marginLeft: '12px' }"
|
||||
animation="flashed"
|
||||
theme="paragraph"
|
||||
/>
|
||||
</view>
|
||||
</scroll-list>
|
||||
</wd-config-provider>
|
||||
|
||||
<view class="fixed bottom-100 left-0 right-0 flex justify-around bg-transparent">
|
||||
@@ -145,21 +130,14 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, getCurrentInstance, onMounted } from 'vue';
|
||||
import moment from '@/sheep/components/moment/moment.vue';
|
||||
import { ref, computed, getCurrentInstance, reactive } from 'vue';
|
||||
import MomentCard from '@/sheep/components/moment-card/moment-card.vue';
|
||||
import ScrollList from '@/sheep/components/scroll-list/scroll-list.vue';
|
||||
import useScroll from '@/sheep/hooks/use-scroll';
|
||||
import RecentApi from '@/sheep/api/member/recent';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
|
||||
const {
|
||||
listData,
|
||||
refresherTriggered,
|
||||
loadMoreContent,
|
||||
loadMoreStatus,
|
||||
onRefresherRefresh,
|
||||
onRefresherAbort,
|
||||
onScrollToLower,
|
||||
onClickLoadMore,
|
||||
} = useScroll(RecentApi.quickPage, {
|
||||
const params = reactive({
|
||||
scene: 'DYNAMIC_RECOMMEND',
|
||||
province: '',
|
||||
city: '',
|
||||
@@ -169,7 +147,11 @@
|
||||
const scrollTop = ref(0);
|
||||
const userDetail = ref<any>({});
|
||||
|
||||
onMounted(() => {
|
||||
onLoad((options: any) => {
|
||||
const { memberId } = options;
|
||||
if (!memberId) return uni.showToast({ title: '参数错误', icon: 'none' });
|
||||
params.memberId = memberId;
|
||||
|
||||
const instance: any = getCurrentInstance()?.proxy;
|
||||
const eventChannel = instance.getOpenerEventChannel();
|
||||
|
||||
@@ -178,6 +160,11 @@
|
||||
});
|
||||
});
|
||||
|
||||
const { listData, loadMoreStatus, refreshList, listLoadMore } = useScroll(
|
||||
RecentApi.quickPage,
|
||||
params,
|
||||
);
|
||||
|
||||
const filterStyle = computed(() => {
|
||||
let blur = 0;
|
||||
const scrollY = scrollTop.value;
|
||||
|
||||
+42
-68
@@ -14,99 +14,73 @@
|
||||
</template>
|
||||
</wd-navbar>
|
||||
|
||||
<scroll-view
|
||||
<scroll-list
|
||||
style="height: calc(100dvh - 44px - 50px)"
|
||||
scroll-y
|
||||
scroll-with-animation
|
||||
refresher-enabled
|
||||
refresher-background="#222"
|
||||
:refresher-triggered="refresherTriggered"
|
||||
:refresher-threshold="100"
|
||||
@refresherrefresh="onRefresherRefresh"
|
||||
@refresherabort="onRefresherAbort"
|
||||
@scrolltolower="onScrollToLower"
|
||||
:loadMoreStatus="loadMoreStatus"
|
||||
@refresh="refreshList"
|
||||
@loadMore="listLoadMore"
|
||||
>
|
||||
<view class="flex px-4 py-2" v-for="user in listData" :key="user.id" @click="detail(user)">
|
||||
<image
|
||||
class="w-200rpx h-300rpx mr-3 rounded-2 bg-#777"
|
||||
:src="user.member.memberAvatar"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<view class="flex-1">
|
||||
<view class="flex justify-between items-center">
|
||||
<text class="text-size-base">{{ user.member.memberNickname }}</text>
|
||||
<text class="px-2 rounded-full text-xs bg-color-theme-dark">{{ '在线' }}</text>
|
||||
</view>
|
||||
<view class="mt-2">
|
||||
<text class="px-2 text-xs c-black rounded-full bg-color-theme-dark">真人认证</text>
|
||||
</view>
|
||||
<view class="mt-2 flex flex-wrap gap-3">
|
||||
<text class="bg-#333 text-color-theme text-xs px-2 rounded-1">
|
||||
{{ user.gender || '未知性别' }}·{{ user.member.memberAge }}岁
|
||||
</text>
|
||||
<text class="bg-#333 text-color-theme text-xs px-2 rounded-1">
|
||||
{{ user.member.memberHeight }}cm
|
||||
</text>
|
||||
<text class="bg-#333 text-color-theme text-xs px-2 rounded-1">
|
||||
{{ user.member.memberWeight }}kg
|
||||
</text>
|
||||
<text class="bg-#333 text-color-theme text-xs px-2 rounded-1">
|
||||
{{ user.member.memberOcc }}
|
||||
</text>
|
||||
<text class="bg-#333 text-color-theme text-xs px-2 rounded-1">
|
||||
{{ user.issueCity }}km
|
||||
</text>
|
||||
</view>
|
||||
<user-card
|
||||
v-if="listData.length"
|
||||
v-for="user in listData"
|
||||
:key="user.id"
|
||||
:data="user"
|
||||
@click="detail(user)"
|
||||
/>
|
||||
<view v-else class="py-2 px-4" v-for="index in 4" :key="index">
|
||||
<view class="flex">
|
||||
<wd-skeleton :row-col="[{ size: '100px', type: 'rect' }]" animation="gradient" />
|
||||
<wd-skeleton
|
||||
:custom-style="{ width: '100%', marginLeft: '12px' }"
|
||||
:row-col="[{ width: '100%' }, { width: '100%' }]"
|
||||
animation="gradient"
|
||||
/>
|
||||
</view>
|
||||
<view class="flex -mt-50px">
|
||||
<wd-skeleton :row-col="[{ size: '100px', type: 'rect' }]" animation="gradient" />
|
||||
<wd-skeleton
|
||||
:custom-style="{ width: '100%', marginLeft: '12px' }"
|
||||
:row-col="[{ width: '100%' }, { width: '50%' }]"
|
||||
animation="gradient"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<uni-load-more
|
||||
:status="loadMoreStatus"
|
||||
:content-text="loadMoreContent"
|
||||
@clickLoadMore="onClickLoadMore"
|
||||
/>
|
||||
<view style="height: 100rpx"></view>
|
||||
</scroll-view>
|
||||
</scroll-list>
|
||||
</wd-config-provider>
|
||||
|
||||
<s-auth-modal />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
import { computed, reactive, ref } from 'vue';
|
||||
import segmented from '@/sheep/components/segmented/segmented.vue';
|
||||
import RecentApi from '@/sheep/api/member/recent';
|
||||
import ScrollList from '@/sheep/components/scroll-list/scroll-list.vue';
|
||||
import UserCard from '@/sheep/components/user-card/user-card.vue';
|
||||
import useScroll from '@/sheep/hooks/use-scroll';
|
||||
// @ts-ignore
|
||||
import sheep from '@/sheep';
|
||||
|
||||
const {
|
||||
listData,
|
||||
refresherTriggered,
|
||||
loadMoreContent,
|
||||
loadMoreStatus,
|
||||
onRefresherRefresh,
|
||||
onRefresherAbort,
|
||||
onScrollToLower,
|
||||
onClickLoadMore,
|
||||
} = useScroll(RecentApi.quickPage, {
|
||||
const current = ref(0);
|
||||
const segmentedItems = ['广场', '最近', '新人'];
|
||||
const userCity = computed(() => sheep.$store('user').userCity);
|
||||
const params = reactive({
|
||||
scene: 'DYNAMIC_RECOMMEND',
|
||||
province: '',
|
||||
city: '',
|
||||
memberId: '',
|
||||
});
|
||||
|
||||
const current = ref(0);
|
||||
const segmentedItems = ['广场', '最近', '新人'];
|
||||
const userCity = computed(() => {
|
||||
return sheep.$store('user').userCity;
|
||||
});
|
||||
const { listData, loadMoreStatus, refreshList, listLoadMore } = useScroll(
|
||||
RecentApi.quickPage,
|
||||
params,
|
||||
);
|
||||
|
||||
const selectAddress = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/home/city',
|
||||
events: {
|
||||
changeCity: () => {
|
||||
onRefresherRefresh();
|
||||
refreshList();
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -114,7 +88,7 @@
|
||||
|
||||
const detail = (user: any) => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/home/detail',
|
||||
url: `/pages/home/detail?memberId=${user.memberId}`,
|
||||
success: function (res) {
|
||||
res.eventChannel.emit('recentDetail', user);
|
||||
},
|
||||
@@ -123,6 +97,6 @@
|
||||
|
||||
const segmentedChange = ({ currentIndex }: { currentIndex: number }) => {
|
||||
console.log(segmentedItems[currentIndex]);
|
||||
onRefresherRefresh();
|
||||
refreshList();
|
||||
};
|
||||
</script>
|
||||
@@ -8,10 +8,12 @@
|
||||
</view>
|
||||
</template>
|
||||
<template #right>
|
||||
<view class="flex items-center rounded-full h-44rpx bg-color-theme py-1 px-2 text-black">
|
||||
<uni-icons type="chat" size="20" color="#333" />
|
||||
<text class="text-sm c-black">互动消息</text>
|
||||
</view>
|
||||
<navigator url="/pages/" open-type="navigate" hover-class="navigator-hover">
|
||||
<view class="flex items-center rounded-full h-44rpx bg-color-theme py-1 px-2 text-black">
|
||||
<uni-icons type="chat" size="20" color="#333" />
|
||||
<text class="text-sm c-black">互动消息</text>
|
||||
</view>
|
||||
</navigator>
|
||||
</template>
|
||||
</wd-navbar>
|
||||
|
||||
|
||||
@@ -7,20 +7,17 @@
|
||||
</view>
|
||||
</template>
|
||||
<template #right>
|
||||
<uni-icons type="camera" size="28" color="#ffcd32" @click="goPublish"></uni-icons>
|
||||
<navigator url="/pages/moments/publish" open-type="navigate" hover-class="navigator-hover">
|
||||
<uni-icons type="camera" size="28" color="#ffcd32" />
|
||||
</navigator>
|
||||
</template>
|
||||
</wd-navbar>
|
||||
|
||||
<scroll-view
|
||||
style="height: calc(100vh - 44px - 50px)"
|
||||
scroll-y
|
||||
refresher-enabled
|
||||
refresher-background="#222"
|
||||
:refresher-triggered="refresherTriggered"
|
||||
:refresher-threshold="100"
|
||||
@refresherrefresh="onRefresherRefresh"
|
||||
@refresherabort="onRefresherAbort"
|
||||
@scrolltolower="onScrollToLower"
|
||||
<scroll-list
|
||||
style="height: calc(100dvh - 44px - 50px)"
|
||||
:loadMoreStatus="loadMoreStatus"
|
||||
@refresh="refreshList"
|
||||
@loadMore="listLoadMore"
|
||||
>
|
||||
<swiper
|
||||
class="h-300rpx mx-4"
|
||||
@@ -45,65 +42,49 @@
|
||||
/>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<moment
|
||||
<moment-card
|
||||
v-if="listData.length"
|
||||
v-for="item in listData"
|
||||
:avatar="item.member?.memberAvatar"
|
||||
:name="item.member?.memberNickname"
|
||||
:verification="item.verification"
|
||||
:info="`未知性别 · ${item.member?.memberAge}岁 | ${item.member?.memberOcc}`"
|
||||
:content="item.description"
|
||||
:media="[item.coverPic]"
|
||||
:location="item.issueAddress"
|
||||
:likes="item.likes"
|
||||
:comments="item.comments"
|
||||
:data="item"
|
||||
@detail="goDetail(item)"
|
||||
/>
|
||||
<uni-load-more
|
||||
:status="loadMoreStatus"
|
||||
:content-text="loadMoreContent"
|
||||
@clickLoadMore="onClickLoadMore"
|
||||
/>
|
||||
<view class="h-100rpx"></view>
|
||||
</scroll-view>
|
||||
<view v-else class="flex px-4 py-4" v-for="index in 3" :key="index">
|
||||
<wd-skeleton :row-col="[{ size: '50px', type: 'circle' }]" animation="flashed" />
|
||||
<wd-skeleton
|
||||
:custom-style="{ width: '100%', marginLeft: '12px' }"
|
||||
animation="flashed"
|
||||
theme="paragraph"
|
||||
/>
|
||||
</view>
|
||||
</scroll-list>
|
||||
</wd-config-provider>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { reactive, ref } from 'vue';
|
||||
import segmented from '@/sheep/components/segmented/segmented.vue';
|
||||
import moment from '@/sheep/components/moment/moment.vue';
|
||||
import MomentCard from '@/sheep/components/moment-card/moment-card.vue';
|
||||
import ScrollList from '@/sheep/components/scroll-list/scroll-list.vue';
|
||||
import useScroll from '@/sheep/hooks/use-scroll';
|
||||
import RecentApi from '@/sheep/api/member/recent';
|
||||
|
||||
const {
|
||||
listData,
|
||||
refresherTriggered,
|
||||
loadMoreContent,
|
||||
loadMoreStatus,
|
||||
onRefresherRefresh,
|
||||
onRefresherAbort,
|
||||
onScrollToLower,
|
||||
onClickLoadMore,
|
||||
} = useScroll(RecentApi.quickPage, {
|
||||
const params = reactive({
|
||||
scene: 'DYNAMIC_RECOMMEND',
|
||||
province: '',
|
||||
city: '',
|
||||
memberId: '',
|
||||
});
|
||||
|
||||
const { listData, loadMoreStatus, refreshList, listLoadMore } = useScroll(
|
||||
RecentApi.quickPage,
|
||||
params,
|
||||
);
|
||||
const current = ref(0);
|
||||
const segmentedItems = ['动态', '附近'];
|
||||
|
||||
const goPublish = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/moments/publish',
|
||||
});
|
||||
};
|
||||
|
||||
// 查看用户详情
|
||||
const goDetail = (user: any) => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/home/detail',
|
||||
url: `/pages/home/detail?memberId=${user.memberId}`,
|
||||
success: function (res) {
|
||||
res.eventChannel.emit('recentDetail', user);
|
||||
},
|
||||
|
||||
@@ -5,12 +5,14 @@
|
||||
<uni-icons type="back" size="30" color="#ffcd32" @click="back"></uni-icons>
|
||||
</template>
|
||||
<template #right>
|
||||
<view
|
||||
class="bg-color-theme px-3 py-1 rounded-full c-black h-1/2 line-height-normal"
|
||||
@click="publishMoments"
|
||||
>
|
||||
发布
|
||||
</view>
|
||||
<navigator hover-class="navigator-hover">
|
||||
<view
|
||||
class="bg-color-theme px-3 py-1 rounded-full c-black h-1/2 line-height-normal"
|
||||
@click="publishMoments"
|
||||
>
|
||||
发布
|
||||
</view>
|
||||
</navigator>
|
||||
</template>
|
||||
</wd-navbar>
|
||||
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
<template>
|
||||
<scroll-view
|
||||
class="h-full"
|
||||
scroll-y
|
||||
:show-scrollbar="false"
|
||||
:refresher-enabled="refresherEnabled"
|
||||
refresher-background="#222"
|
||||
:refresher-triggered="refresherTriggered"
|
||||
:refresher-threshold="100"
|
||||
@refresherrefresh="onRefresherRefresh"
|
||||
@refresherabort="onRefresherAbort"
|
||||
@scrolltolower="onScrollToLower"
|
||||
>
|
||||
<slot :list="listData" />
|
||||
<uni-load-more
|
||||
:status="loadMoreStatus"
|
||||
:content-text="loadMoreContent"
|
||||
@clickLoadMore="onClickLoadMore"
|
||||
/>
|
||||
<view style="height: 100rpx"></view>
|
||||
</scroll-view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import useScroll from '@/sheep/hooks/use-scroll';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
load?: (...arg: any) => Promise<any>;
|
||||
refresherEnabled?: boolean;
|
||||
requestBody?: any;
|
||||
}>(),
|
||||
{
|
||||
load: () => Promise.resolve([]),
|
||||
refresherEnabled: true,
|
||||
requestBody: {},
|
||||
},
|
||||
);
|
||||
|
||||
const {
|
||||
listData,
|
||||
refresherTriggered,
|
||||
loadMoreContent,
|
||||
loadMoreStatus,
|
||||
onRefresherRefresh,
|
||||
onRefresherAbort,
|
||||
onScrollToLower,
|
||||
onClickLoadMore,
|
||||
} = useScroll(props.load, props.requestBody);
|
||||
|
||||
defineExpose({
|
||||
reload: onRefresherRefresh,
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<scroll-list
|
||||
:loadMoreStatus="loadMoreStatus"
|
||||
@refresh="refreshList"
|
||||
@loadMore="listLoadMore"
|
||||
:show-scrollbar="false"
|
||||
:refresherEnabled="false"
|
||||
>
|
||||
<slot :list="listData" />
|
||||
</scroll-list>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import ScrollList from '@/sheep/components/scroll-list/scroll-list.vue';
|
||||
import useScroll from '@/sheep/hooks/use-scroll';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
load?: (...arg: any) => Promise<any>;
|
||||
requestBody?: any;
|
||||
}>(),
|
||||
{
|
||||
load: () => Promise.resolve([]),
|
||||
requestBody: {},
|
||||
},
|
||||
);
|
||||
|
||||
const { listData, loadMoreStatus, refreshList, listLoadMore } = useScroll(
|
||||
props.load,
|
||||
props.requestBody,
|
||||
);
|
||||
</script>
|
||||
@@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<view class="p-4">
|
||||
<view class="flex items-center justify-between text-color-theme mb-1">
|
||||
<text>我的相册</text>
|
||||
<navigator
|
||||
class="flex-row-center"
|
||||
url="/pages/profile/upload-album"
|
||||
open-type="navigate"
|
||||
hover-class="navigator-hover"
|
||||
>
|
||||
<wd-icon name="add-circle1" size="18px" />
|
||||
<text class="text-28rpx">上传相册</text>
|
||||
</navigator>
|
||||
</view>
|
||||
|
||||
<view class="flex flex-wrap gap-3">
|
||||
<view v-for="(item, index) in ablumList" :key="index" @click="previewPhoto(index)">
|
||||
<image class="size-150rpx rounded-2" :src="item.address" mode="aspectFill" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
export interface AlbumData {
|
||||
resourceType: 'IMAGE' | 'VIDEO';
|
||||
address: string;
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
ablumList: AlbumData[];
|
||||
}>();
|
||||
|
||||
const previewPhoto = (current: number) => {
|
||||
if (!props.ablumList.length) return;
|
||||
const urls = props.ablumList.map((item) => item.address);
|
||||
uni.previewImage({
|
||||
current,
|
||||
urls,
|
||||
indicator: 'number',
|
||||
});
|
||||
};
|
||||
</script>
|
||||
@@ -18,45 +18,11 @@
|
||||
:duration="200"
|
||||
>
|
||||
<swiper-item v-for="index in segmentedItems.length" :key="index">
|
||||
<scroll-list :load="load[index]" :refresher-enabled="false">
|
||||
<swiper-scroll class="h-full" :load="load[index]">
|
||||
<template #default="{ list }">
|
||||
<view class="flex px-4 py-2" v-for="user in list" :key="user.id" @click="detail(user)">
|
||||
<image
|
||||
class="w-200rpx h-300rpx mr-3 rounded-2 bg-#777"
|
||||
:src="user.member.memberAvatar"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<view class="flex-1">
|
||||
<view class="flex justify-between items-center">
|
||||
<text class="text-size-base">{{ user.member.memberNickname }}</text>
|
||||
<text class="px-2 rounded-full text-xs bg-color-theme-dark">{{ '在线' }}</text>
|
||||
</view>
|
||||
<view class="mt-2">
|
||||
<text class="px-2 text-xs c-black rounded-full bg-color-theme-dark">
|
||||
真人认证
|
||||
</text>
|
||||
</view>
|
||||
<view class="mt-2 flex flex-wrap gap-3">
|
||||
<text class="bg-#333 text-color-theme text-xs px-2 rounded-1">
|
||||
{{ user.gender || '未知性别' }}·{{ user.member.memberAge }}岁
|
||||
</text>
|
||||
<text class="bg-#333 text-color-theme text-xs px-2 rounded-1">
|
||||
{{ user.member.memberHeight }}cm
|
||||
</text>
|
||||
<text class="bg-#333 text-color-theme text-xs px-2 rounded-1">
|
||||
{{ user.member.memberWeight }}kg
|
||||
</text>
|
||||
<text class="bg-#333 text-color-theme text-xs px-2 rounded-1">
|
||||
{{ user.member.memberOcc }}
|
||||
</text>
|
||||
<text class="bg-#333 text-color-theme text-xs px-2 rounded-1">
|
||||
{{ user.issueCity }}km
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<user-card v-for="user in list" :key="user.id" :data="user" @click="detail(user)" />
|
||||
</template>
|
||||
</scroll-list>
|
||||
</swiper-scroll>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</wd-config-provider>
|
||||
@@ -66,8 +32,9 @@
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import { ref } from 'vue';
|
||||
import segmented from '@/sheep/components/segmented/segmented.vue';
|
||||
import UserCard from '@/sheep/components/user-card/user-card.vue';
|
||||
import SwiperScroll from './components/swiper-scroll.vue';
|
||||
import RecentApi from '@/sheep/api/member/recent';
|
||||
import scrollList from './components/scroll-list.vue';
|
||||
|
||||
const current = ref<0 | 1 | number>(0);
|
||||
const segmentedItems = ['我喜欢', '喜欢我'];
|
||||
@@ -80,7 +47,7 @@
|
||||
|
||||
const detail = (user: any) => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/home/detail',
|
||||
url: `/pages/home/detail?memberId=${user.memberId}`,
|
||||
success: function (res) {
|
||||
res.eventChannel.emit('recentDetail', user);
|
||||
},
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<wd-config-provider theme="dark">
|
||||
<wd-navbar title="我的动态" safeAreaInsetTop :bordered="false">
|
||||
<template #left>
|
||||
<navigator open-type="navigateBack" hover-class="navigator-hover">
|
||||
<uni-icons type="back" size="30" color="#ffcd32"></uni-icons>
|
||||
</navigator>
|
||||
</template>
|
||||
<template #right>
|
||||
<navigator url="/pages/moments/publish" open-type="navigate" hover-class="navigator-hover">
|
||||
<view class="bg-color-theme px-3 py-1 rounded-full c-black h-1/2 line-height-normal">
|
||||
发布动态
|
||||
</view>
|
||||
</navigator>
|
||||
</template>
|
||||
</wd-navbar>
|
||||
|
||||
<scroll-list
|
||||
style="height: calc(100dvh - 44px - 50px)"
|
||||
:loadMoreStatus="loadMoreStatus"
|
||||
@refresh="refreshList"
|
||||
@loadMore="listLoadMore"
|
||||
>
|
||||
<moment-card v-if="listData.length" v-for="item in listData" :data="item" />
|
||||
<view v-else class="flex px-4 py-4" v-for="index in 4" :key="index">
|
||||
<wd-skeleton :row-col="[{ size: '50px', type: 'circle' }]" animation="flashed" />
|
||||
<wd-skeleton
|
||||
:custom-style="{ width: '100%', marginLeft: '12px' }"
|
||||
animation="flashed"
|
||||
theme="paragraph"
|
||||
/>
|
||||
</view>
|
||||
</scroll-list>
|
||||
</wd-config-provider>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import MomentCard from '@/sheep/components/moment-card/moment-card.vue';
|
||||
import ScrollList from '@/sheep/components/scroll-list/scroll-list.vue';
|
||||
import useScroll from '@/sheep/hooks/use-scroll';
|
||||
import RecentApi from '@/sheep/api/member/recent';
|
||||
import { reactive } from 'vue';
|
||||
|
||||
const params = reactive({});
|
||||
const { listData, loadMoreStatus, refreshList, listLoadMore } = useScroll(
|
||||
RecentApi.myMomentList,
|
||||
params,
|
||||
);
|
||||
</script>
|
||||
+120
-35
@@ -3,60 +3,73 @@
|
||||
<wd-config-provider theme="dark">
|
||||
<wd-navbar title="我的" safeAreaInsetTop :bordered="false">
|
||||
<template #right>
|
||||
<view
|
||||
class="flex items-center rounded-full h-44rpx bg-color-theme py-1 px-2 text-black"
|
||||
@click="editUserInfo"
|
||||
>
|
||||
<uni-icons type="auth" size="20" color="#333"></uni-icons>
|
||||
<text class="text-sm">编辑资料</text>
|
||||
</view>
|
||||
<navigator hover-class="navigator-hover">
|
||||
<view
|
||||
class="flex items-center rounded-full h-44rpx bg-color-theme py-1 px-2 text-black"
|
||||
@click="editUserInfo"
|
||||
>
|
||||
<uni-icons type="auth" size="20" color="#333"></uni-icons>
|
||||
<text class="text-sm">编辑资料</text>
|
||||
</view>
|
||||
</navigator>
|
||||
</template>
|
||||
</wd-navbar>
|
||||
|
||||
<scroll-view class="h-[calc(100vh-144rpx)]" scroll-y>
|
||||
<!-- 个人信息 -->
|
||||
<view class="flex items-center p-6">
|
||||
<image :src="userInfo.avatar" class="mr-4 size-100px rounded-full bg-#333" />
|
||||
<image
|
||||
:src="userInfo.avatar"
|
||||
class="mr-4 size-100px rounded-full bg-#333 border border-amber border-solid"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<view class="flex-1">
|
||||
<view class="mb-1 text-lg">{{ userInfo.nickname }}</view>
|
||||
<view class="mb-1 text-xs text-#ffffff80">ID: {{ userInfo.id }}</view>
|
||||
<view class="inline-block rounded-full bg-color-theme px-2 text-xs c-black">
|
||||
{{ 'vip' }}
|
||||
</view>
|
||||
<view class="mb-1 text-base">{{ userInfo.nickname }}</view>
|
||||
<view class="mb-2 text-xs text-#ffffff80">ID: {{ userInfo.id }}</view>
|
||||
<text class="bg-#333 text-color-theme-dark text-xs px-2 py-1 rounded-1 truncate">
|
||||
{{ userCity?.t || '' }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 我喜欢和钱包 -->
|
||||
<view class="flex justify-around my-4 text-base">
|
||||
<view class="flex flex-col items-center" @click="goLike(0)">
|
||||
<text class="text-color-theme font-bold">{{ 1 }}</text>
|
||||
<text class="text-color-theme">我喜欢</text>
|
||||
<text class="text-color-theme font-600 text-lg">{{ 1 }}</text>
|
||||
<text class="text-color-theme text-xs">我喜欢</text>
|
||||
</view>
|
||||
<view class="flex flex-col items-center" @click="goLike(1)">
|
||||
<text class="text-color-theme font-bold">{{ 1 }}</text>
|
||||
<text class="text-color-theme">喜欢我</text>
|
||||
<text class="text-color-theme font-600 text-lg">{{ 2 }}</text>
|
||||
<text class="text-color-theme text-xs">喜欢我</text>
|
||||
</view>
|
||||
<view class="flex flex-col items-center">
|
||||
<text class="text-color-theme font-bold">{{ 1 }}</text>
|
||||
<text class="text-color-theme">钱包</text>
|
||||
<text class="text-color-theme font-600 text-lg">{{ 3 }}</text>
|
||||
<text class="text-color-theme text-xs">钱包</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 用户相册 -->
|
||||
<user-ablum :ablumList="ablumList"></user-ablum>
|
||||
|
||||
<!-- 菜单 -->
|
||||
<view class="mt-4 mx-1">
|
||||
<wd-cell-group>
|
||||
<wd-cell title="我的收益" value="" is-link to=""></wd-cell>
|
||||
<wd-cell title="访客记录" value="" is-link></wd-cell>
|
||||
<wd-cell title="认证中心" value="" is-link></wd-cell>
|
||||
<wd-cell title="我的动态" value="" is-link></wd-cell>
|
||||
<wd-cell title="我的评价" value="" is-link></wd-cell>
|
||||
<wd-cell title="问题反馈" value="" is-link></wd-cell>
|
||||
<wd-cell title="客服助手" value="" is-link></wd-cell>
|
||||
<wd-cell title="关注公众号" value="" is-link></wd-cell>
|
||||
<wd-cell title="设置" value="" is-link></wd-cell>
|
||||
<wd-cell
|
||||
v-for="(item, index) in MenuCellList"
|
||||
:key="index"
|
||||
:title="item.title"
|
||||
:value="item.value"
|
||||
icon-size="24"
|
||||
:icon="item.icon"
|
||||
is-link
|
||||
ellipsis
|
||||
:to="item.to"
|
||||
@click="item.click"
|
||||
/>
|
||||
</wd-cell-group>
|
||||
</view>
|
||||
<view
|
||||
class="mt-40rpx rounded-full bg-color-theme-dark text-base text-center py-2 mx-8"
|
||||
class="mt-40rpx rounded-full bg-color-theme-dark text-base text-center py-2 mx-8 active:bg-color-theme"
|
||||
@click="handleLogout"
|
||||
>
|
||||
退 出 登 录
|
||||
@@ -65,21 +78,70 @@
|
||||
</scroll-view>
|
||||
|
||||
<wd-message-box />
|
||||
<wd-popup
|
||||
v-model="myEvaluationShow"
|
||||
custom-style="border-radius:32rpx;"
|
||||
closable
|
||||
:safe-area-inset-bottom="true"
|
||||
>
|
||||
<view class="w-90vw h-400rpx flex-col-center gap-4 flex-wrap">
|
||||
<view class="text-color-theme text-lg">我的评价</view>
|
||||
<view class="w-90% flex justify-around">
|
||||
<view class="bg-color-theme-dark flex items-center p-1 rounded-1">
|
||||
<text class="mr-2 text-xs">身材</text>
|
||||
<wd-rate v-model="myEvaluation.a" readonly />
|
||||
</view>
|
||||
<view class="bg-color-theme-dark flex items-center p-1 rounded-1">
|
||||
<text class="mr-2 text-xs">颜值</text>
|
||||
<wd-rate v-model="myEvaluation.a" readonly />
|
||||
</view>
|
||||
</view>
|
||||
<view class="w-90% flex justify-around">
|
||||
<view class="bg-color-theme-dark flex items-center p-1 rounded-1">
|
||||
<text class="mr-2 text-xs">有趣</text>
|
||||
<wd-rate v-model="myEvaluation.a" readonly />
|
||||
</view>
|
||||
<view class="bg-color-theme-dark flex items-center p-1 rounded-1">
|
||||
<text class="mr-2 text-xs">耐心</text>
|
||||
<wd-rate v-model="myEvaluation.a" readonly />
|
||||
</view>
|
||||
</view>
|
||||
<view class="text-color-theme text-lg">综合评分 1.0</view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
<wd-curtain
|
||||
v-model="curtainShow"
|
||||
src="https://img20.360buyimg.com/da/jfs/t1/141592/25/8861/261559/5f68d8c1E33ed78ab/698ad655bfcfbaed.png"
|
||||
close-position="top-right"
|
||||
:width="300"
|
||||
close-on-click-modal
|
||||
show-menu-by-longpress
|
||||
/>
|
||||
</wd-config-provider>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { computed, reactive, ref } from 'vue';
|
||||
import UserAblum from './components/user-ablum.vue';
|
||||
import useAblum from './use-ablum';
|
||||
// @ts-ignore
|
||||
import sheep from '@/sheep';
|
||||
import { useMessage } from '@/uni_modules/wot-design-uni';
|
||||
import RecentApi from '@/sheep/api/member/recent';
|
||||
|
||||
const message = useMessage();
|
||||
const { ablumList } = useAblum();
|
||||
|
||||
const userInfo = computed(() => {
|
||||
return sheep.$store('user').userInfo;
|
||||
const userCity = computed(() => sheep.$store('user').userCity);
|
||||
const myEvaluationShow = ref(false); // 我的评价弹窗
|
||||
// 我的评价数据
|
||||
const myEvaluation = reactive({
|
||||
a: 0,
|
||||
});
|
||||
const curtainShow = ref(false); // 关注公众号弹窗
|
||||
const userInfo = computed(() => sheep.$store('user').userInfo);
|
||||
|
||||
// 修改用户信息
|
||||
const editUserInfo = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/profile/userinfo',
|
||||
@@ -93,6 +155,18 @@
|
||||
});
|
||||
};
|
||||
|
||||
// 查看我的评价
|
||||
const lookMyEvaluation = async () => {
|
||||
await RecentApi.myEvaluate();
|
||||
myEvaluation.a = 1;
|
||||
myEvaluationShow.value = true;
|
||||
};
|
||||
|
||||
// 关注公众号
|
||||
const subOfficial = () => {
|
||||
curtainShow.value = true;
|
||||
};
|
||||
|
||||
// 退出登录
|
||||
const handleLogout = () => {
|
||||
message
|
||||
@@ -104,8 +178,19 @@
|
||||
sheep.$store('user').logout();
|
||||
uni.redirectTo({ url: '/pages/login/login' });
|
||||
})
|
||||
.catch(() => {
|
||||
console.log('点击了取消按钮');
|
||||
});
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// cell菜单
|
||||
const MenuCellList = [
|
||||
{ title: '我的收益', value: '', icon: 'wallet', to: '' },
|
||||
{ title: '访客记录√', value: '', icon: 'dong', to: '/pages/profile/view-record' },
|
||||
{ title: '认证中心', value: '', icon: 'user', to: '' },
|
||||
{ title: '我的动态√', value: '', icon: 'star', to: '/pages/profile/my-moment' },
|
||||
{ title: '我的评价√', value: '', icon: 'view-module', to: '', click: lookMyEvaluation },
|
||||
{ title: '问题反馈', value: '', icon: 'backtop-rectangle', to: '' },
|
||||
{ title: '客服助手', value: '', icon: 'service', to: '' },
|
||||
{ title: '关注公众号√', value: '获取最新消息', icon: 'qrcode', to: '', click: subOfficial },
|
||||
{ title: '设置', value: '', icon: 'setting1', to: '' },
|
||||
];
|
||||
</script>
|
||||
@@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<wd-config-provider theme="dark">
|
||||
<wd-navbar title="上传相册" safeAreaInsetTop :bordered="false">
|
||||
<template #left>
|
||||
<navigator open-type="navigateBack" hover-class="navigator-hover">
|
||||
<uni-icons type="back" size="30" color="#ffcd32"></uni-icons>
|
||||
</navigator>
|
||||
</template>
|
||||
</wd-navbar>
|
||||
|
||||
<view class="mx-5 my-3 flex justify-between text-color-theme">
|
||||
<text>相册</text>
|
||||
<text>{{ ablumUrlList?.length || 0 }}/10</text>
|
||||
</view>
|
||||
<view class="px-4">
|
||||
<wd-upload v-model:file-list="ablumUrlList" :upload-method="customUpload"></wd-upload>
|
||||
</view>
|
||||
</wd-config-provider>
|
||||
|
||||
<view @click="save">保存</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue';
|
||||
import SUploader from '@/sheep/components/s-uploader/s-uploader.vue';
|
||||
import useAblum from './use-ablum';
|
||||
import {
|
||||
UploadFile,
|
||||
UploadMethod,
|
||||
} from '@/uni_modules/wot-design-uni/components/wd-upload/types';
|
||||
import FileApi from '@/sheep/api/infra/file';
|
||||
|
||||
const { ablumList, getUserAlbum } = useAblum();
|
||||
const ablumUrlList = ref<UploadFile[]>([]);
|
||||
|
||||
watch(
|
||||
() => ablumList.value,
|
||||
(val) => {
|
||||
ablumUrlList.value = val.map((item) => ({ url: item.address }));
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
const customUpload: UploadMethod = async (file, formData, options) => {
|
||||
const { data } = await FileApi.uploadFile(file.url);
|
||||
options.onSuccess(data, file, formData);
|
||||
console.log(data);
|
||||
console.log(ablumUrlList.value);
|
||||
};
|
||||
|
||||
// 保存相册
|
||||
const save = async () => {
|
||||
// TODO: 调用保存相册的 API
|
||||
// await RecentApi.saveUserAlbum(ablumList.value);
|
||||
// 保存成功后重新获取相册列表
|
||||
await getUserAlbum();
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,19 @@
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { AlbumData } from './components/user-ablum.vue';
|
||||
import RecentApi from '@/sheep/api/member/recent';
|
||||
|
||||
export default function useAblum() {
|
||||
const ablumList = ref<AlbumData[]>([]); // 用户相册
|
||||
|
||||
// 获取用户相册
|
||||
const getUserAlbum = async () => {
|
||||
const { data = null } = await RecentApi.getUserAlbum({ pageNo: 1, pageSize: 10 });
|
||||
ablumList.value = data.list ?? [];
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getUserAlbum();
|
||||
});
|
||||
|
||||
return { ablumList, getUserAlbum };
|
||||
}
|
||||
@@ -11,12 +11,14 @@
|
||||
<uni-icons type="back" size="30" color="#ffcd32" @click="back"></uni-icons>
|
||||
</template>
|
||||
<template #right>
|
||||
<view
|
||||
class="bg-color-theme px-3 py-1 rounded-full c-black h-1/2 line-height-normal"
|
||||
@click="saveUserInfo"
|
||||
>
|
||||
保存
|
||||
</view>
|
||||
<navigator hover-class="navigator-hover">
|
||||
<view
|
||||
class="bg-color-theme px-3 py-1 rounded-full c-black h-1/2 line-height-normal"
|
||||
@click="saveUserInfo"
|
||||
>
|
||||
保存
|
||||
</view>
|
||||
</navigator>
|
||||
</template>
|
||||
</wd-navbar>
|
||||
|
||||
@@ -131,7 +133,7 @@
|
||||
import { reactive } from 'vue';
|
||||
// @ts-ignore
|
||||
import UserApi from '@/sheep/api/member/user';
|
||||
import sUploader from '@/sheep/components/s-uploader/s-uploader.vue';
|
||||
import SUploader from '@/sheep/components/s-uploader/s-uploader.vue';
|
||||
// @ts-ignore
|
||||
import sheep from '@/sheep';
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<wd-config-provider theme="dark">
|
||||
<wd-navbar title="访客记录" safeAreaInsetTop :bordered="false">
|
||||
<template #left>
|
||||
<navigator open-type="navigateBack" hover-class="navigator-hover">
|
||||
<uni-icons type="back" size="30" color="#ffcd32"></uni-icons>
|
||||
</navigator>
|
||||
</template>
|
||||
</wd-navbar>
|
||||
|
||||
<wd-tabs v-model="activeTab">
|
||||
<wd-tab title="我看过的">
|
||||
<view>1</view>
|
||||
</wd-tab>
|
||||
<wd-tab title="看过我的">
|
||||
<view>2</view>
|
||||
</wd-tab>
|
||||
</wd-tabs>
|
||||
|
||||
<scroll-list
|
||||
style="height: calc(100dvh - 44px - 42px)"
|
||||
:loadMoreStatus="loadMoreStatus"
|
||||
@refresh="refreshList"
|
||||
@loadMore="listLoadMore"
|
||||
>
|
||||
<moment-card v-if="listData.length" v-for="item in 4" :data="item" />
|
||||
<view v-else class="flex px-4 py-4" v-for="index in 4" :key="index">
|
||||
<wd-skeleton :row-col="[{ size: '50px', type: 'circle' }]" animation="flashed" />
|
||||
<wd-skeleton
|
||||
:custom-style="{ width: '100%', marginLeft: '12px' }"
|
||||
animation="flashed"
|
||||
theme="paragraph"
|
||||
/>
|
||||
</view>
|
||||
</scroll-list>
|
||||
</wd-config-provider>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import MomentCard from '@/sheep/components/moment-card/moment-card.vue';
|
||||
import ScrollList from '@/sheep/components/scroll-list/scroll-list.vue';
|
||||
import useScroll from '@/sheep/hooks/use-scroll';
|
||||
import RecentApi from '@/sheep/api/member/recent';
|
||||
import { ref, reactive } from 'vue';
|
||||
|
||||
const activeTab = ref();
|
||||
const params = reactive({});
|
||||
const { listData, loadMoreStatus, refreshList, listLoadMore } = useScroll(
|
||||
RecentApi.viewRecord,
|
||||
params,
|
||||
);
|
||||
</script>
|
||||
@@ -51,6 +51,64 @@ const RecentApi = {
|
||||
},
|
||||
});
|
||||
},
|
||||
// 查看我的动态
|
||||
myMomentList: (data: any) => {
|
||||
return request({
|
||||
url: '/member/recent/xxx/xxx',
|
||||
method: 'POST',
|
||||
data,
|
||||
custom: {
|
||||
showLoading: true,
|
||||
loadingMsg: '加载中',
|
||||
},
|
||||
});
|
||||
},
|
||||
// 查看访客记录
|
||||
viewRecord: (data: any) => {
|
||||
return request({
|
||||
url: '/member/recent/xxx/xxx',
|
||||
method: 'POST',
|
||||
data,
|
||||
custom: {
|
||||
showLoading: true,
|
||||
loadingMsg: '加载中',
|
||||
},
|
||||
});
|
||||
},
|
||||
// 查看我的评价
|
||||
myEvaluate: () => {
|
||||
return request({
|
||||
url: '/member/recent/xxx/xxx',
|
||||
method: 'POST',
|
||||
custom: {
|
||||
showLoading: true,
|
||||
loadingMsg: '加载中',
|
||||
},
|
||||
});
|
||||
},
|
||||
// 用户朋友圈操作
|
||||
recentOperate: (data: any) => {
|
||||
return request({
|
||||
url: '/member/recent/operate',
|
||||
method: 'POST',
|
||||
data,
|
||||
custom: {
|
||||
showLoading: true,
|
||||
loadingMsg: '操作中',
|
||||
},
|
||||
});
|
||||
},
|
||||
// 获取用户相册
|
||||
getUserAlbum: (params: any) => {
|
||||
return request({
|
||||
url: '/member/photo/page',
|
||||
method: 'GET',
|
||||
params,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default RecentApi;
|
||||
@@ -1,196 +0,0 @@
|
||||
<!-- TODO 霖:是不是怎么复用 s-count-down 组件 -->
|
||||
<template>
|
||||
<view class="time" :style="justifyLeft">
|
||||
<text class="" v-if="tipText">{{ tipText }}</text>
|
||||
<text
|
||||
class="styleAll p6"
|
||||
v-if="isDay === true"
|
||||
:style="{ background: bgColor.bgColor, color: bgColor.Color }"
|
||||
>{{ day }}{{ bgColor.isDay ? '天' : '' }}</text
|
||||
>
|
||||
<text
|
||||
class="timeTxt"
|
||||
v-if="dayText"
|
||||
:style="{ width: bgColor.timeTxtwidth, color: bgColor.bgColor }"
|
||||
>{{ dayText }}</text
|
||||
>
|
||||
<text
|
||||
class="styleAll"
|
||||
:class="isCol ? 'timeCol' : ''"
|
||||
:style="{ background: bgColor.bgColor, color: bgColor.Color, width: bgColor.width }"
|
||||
>{{ hour }}</text
|
||||
>
|
||||
<text
|
||||
class="timeTxt"
|
||||
v-if="hourText"
|
||||
:class="isCol ? 'whit' : ''"
|
||||
:style="{ width: bgColor.timeTxtwidth, color: bgColor.bgColor }"
|
||||
>{{ hourText }}</text
|
||||
>
|
||||
<text
|
||||
class="styleAll"
|
||||
:class="isCol ? 'timeCol' : ''"
|
||||
:style="{ background: bgColor.bgColor, color: bgColor.Color, width: bgColor.width }"
|
||||
>{{ minute }}</text
|
||||
>
|
||||
<text
|
||||
class="timeTxt"
|
||||
v-if="minuteText"
|
||||
:class="isCol ? 'whit' : ''"
|
||||
:style="{ width: bgColor.timeTxtwidth, color: bgColor.bgColor }"
|
||||
>{{ minuteText }}</text
|
||||
>
|
||||
<text
|
||||
class="styleAll"
|
||||
:class="isCol ? 'timeCol' : ''"
|
||||
:style="{ background: bgColor.bgColor, color: bgColor.Color, width: bgColor.width }"
|
||||
>{{ second }}</text
|
||||
>
|
||||
<text class="timeTxt" v-if="secondText">{{ secondText }}</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'countDown',
|
||||
props: {
|
||||
justifyLeft: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
//距离开始提示文字
|
||||
tipText: {
|
||||
type: String,
|
||||
default: '倒计时',
|
||||
},
|
||||
dayText: {
|
||||
type: String,
|
||||
default: '天',
|
||||
},
|
||||
hourText: {
|
||||
type: String,
|
||||
default: '时',
|
||||
},
|
||||
minuteText: {
|
||||
type: String,
|
||||
default: '分',
|
||||
},
|
||||
secondText: {
|
||||
type: String,
|
||||
default: '秒',
|
||||
},
|
||||
datatime: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
isDay: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
isCol: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
bgColor: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
day: '00',
|
||||
hour: '00',
|
||||
minute: '00',
|
||||
second: '00',
|
||||
};
|
||||
},
|
||||
created: function () {
|
||||
this.show_time();
|
||||
},
|
||||
mounted: function () {},
|
||||
methods: {
|
||||
show_time: function () {
|
||||
let that = this;
|
||||
|
||||
function runTime() {
|
||||
//时间函数
|
||||
let intDiff = that.datatime - Date.parse(new Date()) / 1000; //获取数据中的时间戳的时间差;
|
||||
let day = 0,
|
||||
hour = 0,
|
||||
minute = 0,
|
||||
second = 0;
|
||||
if (intDiff > 0) {
|
||||
//转换时间
|
||||
if (that.isDay === true) {
|
||||
day = Math.floor(intDiff / (60 * 60 * 24));
|
||||
} else {
|
||||
day = 0;
|
||||
}
|
||||
hour = Math.floor(intDiff / (60 * 60)) - day * 24;
|
||||
minute = Math.floor(intDiff / 60) - day * 24 * 60 - hour * 60;
|
||||
second = Math.floor(intDiff) - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60;
|
||||
if (hour <= 9) hour = '0' + hour;
|
||||
if (minute <= 9) minute = '0' + minute;
|
||||
if (second <= 9) second = '0' + second;
|
||||
that.day = day;
|
||||
that.hour = hour;
|
||||
that.minute = minute;
|
||||
that.second = second;
|
||||
} else {
|
||||
that.day = '00';
|
||||
that.hour = '00';
|
||||
that.minute = '00';
|
||||
that.second = '00';
|
||||
}
|
||||
}
|
||||
runTime();
|
||||
setInterval(runTime, 1000);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.p6 {
|
||||
padding: 0 8rpx;
|
||||
}
|
||||
.styleAll {
|
||||
/* color: #fff; */
|
||||
font-size: 24rpx;
|
||||
height: 36rpx;
|
||||
line-height: 36rpx;
|
||||
border-radius: 6rpx;
|
||||
text-align: center;
|
||||
/* padding: 0 6rpx; */
|
||||
}
|
||||
.timeTxt {
|
||||
text-align: center;
|
||||
/* width: 16rpx; */
|
||||
height: 36rpx;
|
||||
line-height: 36rpx;
|
||||
display: inline-block;
|
||||
}
|
||||
.whit {
|
||||
color: #fff !important;
|
||||
}
|
||||
.time {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.red {
|
||||
color: #fc4141;
|
||||
margin: 0 4rpx;
|
||||
}
|
||||
|
||||
.timeCol {
|
||||
/* width: 40rpx;
|
||||
height: 40rpx;
|
||||
line-height: 40rpx;
|
||||
text-align:center;
|
||||
border-radius: 6px;
|
||||
background: #fff;
|
||||
font-size: 24rpx; */
|
||||
color: #e93323;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,136 @@
|
||||
<template>
|
||||
<view class="border-1 border-b-solid border-#444444 px-4 py-4">
|
||||
<view class="mb-1 flex items-center" @click="detail">
|
||||
<image
|
||||
:src="member.memberAvatar"
|
||||
class="mr-3 size-100rpx rounded-full bg-#333333"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<view class="flex-1">
|
||||
<view class="flex justify-between items-center">
|
||||
<view class="flex items-center">
|
||||
<text class="mr-4 text-base">{{ member?.memberNickname }}</text>
|
||||
<view
|
||||
class="inline-flex items-center px-1 text-20rpx text-black rounded-1 bg-color-theme-dark"
|
||||
>
|
||||
<wd-icon name="discount-filled" size="12px" color="#000"></wd-icon>
|
||||
<text>真人认证</text>
|
||||
</view>
|
||||
</view>
|
||||
<text class="text-22rpx c-gray">近期</text>
|
||||
</view>
|
||||
<view class="mt-1 text-xs c-gray">
|
||||
{{ `未知性别 · ${member?.memberAge}岁 | ${member?.memberOcc}` }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mb-30rpx pl-130rpx">
|
||||
<text class="leading-[1.5] text-white">{{ data.description }}</text>
|
||||
<view
|
||||
class="mt-20rpx flex flex-wrap gap-20rpx"
|
||||
v-if="data.coverPic && data.coverPic.length > 0"
|
||||
>
|
||||
<template v-for="item in [data.coverPic]">
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<su-video v-if="item.endsWith('mp4')" :src="item" />
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef APP-PLUS -->
|
||||
<video v-if="item.endsWith('mp4')" :src="item" />
|
||||
<!-- #endif -->
|
||||
<image
|
||||
v-else
|
||||
v-if="item.startsWith('http')"
|
||||
:src="item"
|
||||
class="size-260rpx rounded-10rpx bg-#333333"
|
||||
mode="aspectFill"
|
||||
@click="previewImage(item)"
|
||||
/>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mb-2 flex items-center pl-130rpx text-xs text-white/70">
|
||||
<uni-icons type="location" size="16" color="#B5B4BC"></uni-icons>
|
||||
<text>{{ data.issueAddress }} · 1km</text>
|
||||
</view>
|
||||
<view class="flex gap-60rpx pl-130rpx text-white">
|
||||
<view class="flex items-center gap-10rpx text-sm">
|
||||
<uni-icons
|
||||
v-if="isLike"
|
||||
type="heart-filled"
|
||||
size="24"
|
||||
color="#ffcd32"
|
||||
@click="handleunLike"
|
||||
></uni-icons>
|
||||
<uni-icons v-else type="heart" size="24" color="#B5B4BC" @click="handleLike"></uni-icons>
|
||||
<text>{{ data.likes || 0 }} 喜欢</text>
|
||||
</view>
|
||||
<view class="flex items-center gap-10rpx text-sm" @click="goChat">
|
||||
<uni-icons type="chat" size="24" color="#B5B4BC"></uni-icons>
|
||||
<text>{{ data.comments || 0 }} 打招呼</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import RecentApi from '@/sheep/api/member/recent';
|
||||
import { computed, reactive, ref } from 'vue';
|
||||
|
||||
const props = defineProps<{
|
||||
data: any;
|
||||
}>();
|
||||
const emit = defineEmits<(e: 'detail') => void>();
|
||||
|
||||
const member = computed(() => props.data.member || {});
|
||||
const isLike = ref(false);
|
||||
const params = reactive({
|
||||
memberId: 7, // 被操作的用户id
|
||||
memberRecentId: 8, // 用户朋友圈编号-不能为空
|
||||
// 朋友圈操作类型 不能为空
|
||||
// RECENT_LIKE-朋友圈-点赞
|
||||
// RECENT_REPORT-朋友圈-举报
|
||||
// RECENT_SHIELD-朋友圈-屏蔽
|
||||
// MEMBER_COLLECT-用户-收藏
|
||||
// MEMBER_SHIELD-用户-屏蔽
|
||||
// MEMBER_REPORT-用户-举报
|
||||
// MEMBER_RATING-用户-评价
|
||||
action: '',
|
||||
reportType: '1', // 举报类型
|
||||
scoreSc: 5, // 身材评分
|
||||
scoreNx: 4, // 耐心评分
|
||||
scoreSk: 3, // 爽快评分
|
||||
scoreYq: 2, // 有趣评分
|
||||
});
|
||||
|
||||
// 图片预览
|
||||
const previewImage = (img: string) => {
|
||||
uni.previewImage({
|
||||
urls: [img],
|
||||
});
|
||||
};
|
||||
|
||||
// 喜欢
|
||||
const handleLike = async () => {
|
||||
params.action = 'RECENT_LIKE';
|
||||
const { code } = await RecentApi.recentOperate(params);
|
||||
if (code == 200) {
|
||||
isLike.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
// 取消喜欢
|
||||
const handleunLike = async () => {
|
||||
await RecentApi.recentOperate(params);
|
||||
isLike.value = false;
|
||||
};
|
||||
|
||||
// 去聊天
|
||||
const goChat = () => {
|
||||
uni.showToast({ title: '功能开发中...' });
|
||||
};
|
||||
|
||||
// 详情
|
||||
const detail = () => {
|
||||
emit('detail');
|
||||
};
|
||||
</script>
|
||||
@@ -1,117 +0,0 @@
|
||||
<template>
|
||||
<view class="border-1 border-b-solid border-#444444 px-4 py-4">
|
||||
<view class="mb-1 flex items-center" @click="detail">
|
||||
<image :src="avatar" class="mr-3 size-100rpx rounded-full bg-#333333" mode="aspectFill" />
|
||||
<view class="flex-1">
|
||||
<view class="flex items-center">
|
||||
<text class="mr-4 text-base">{{ name }}</text>
|
||||
<text class="rounded-6rpx bg-color-theme px-1 text-xs text-black">实人认证</text>
|
||||
</view>
|
||||
<view class="mt-1 text-xs c-gray">{{ info }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mb-30rpx pl-130rpx">
|
||||
<text class="leading-[1.5] text-white">{{ content }}</text>
|
||||
<view class="mt-20rpx flex flex-wrap gap-20rpx" v-if="media && media.length > 0">
|
||||
<template v-for="item in media">
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<su-video v-if="item.endsWith('mp4')" :src="item" />
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef APP-PLUS -->
|
||||
<video v-if="item.endsWith('mp4')" :src="item" />
|
||||
<!-- #endif -->
|
||||
<image
|
||||
v-else
|
||||
v-if="item.startsWith('http')"
|
||||
:src="item"
|
||||
class="size-260rpx rounded-10rpx bg-#333333"
|
||||
mode="aspectFill"
|
||||
@click="previewImage(item)"
|
||||
/>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mb-2 flex items-center pl-130rpx text-xs text-white/70">
|
||||
<uni-icons type="location" size="16" color="#B5B4BC"></uni-icons>
|
||||
<text>{{ location }} · 1km</text>
|
||||
</view>
|
||||
<view class="flex gap-60rpx pl-130rpx text-white">
|
||||
<view class="flex items-center gap-10rpx text-sm">
|
||||
<uni-icons
|
||||
v-if="isLike"
|
||||
type="heart-filled"
|
||||
size="24"
|
||||
color="#ffcd32"
|
||||
@click="handleunLike"
|
||||
></uni-icons>
|
||||
<uni-icons v-else type="heart" size="24" color="#B5B4BC" @click="handleLike"></uni-icons>
|
||||
<text>{{ likes || 0 }} 喜欢</text>
|
||||
</view>
|
||||
<view class="flex items-center gap-10rpx text-sm" @click="goChat">
|
||||
<uni-icons type="chat" size="24" color="#B5B4BC"></uni-icons>
|
||||
<text>{{ comments || 0 }} 打招呼</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
|
||||
withDefaults(
|
||||
defineProps<
|
||||
Partial<{
|
||||
avatar: string;
|
||||
name: string;
|
||||
verification: boolean;
|
||||
info: string;
|
||||
content: string;
|
||||
media: string[];
|
||||
location: string;
|
||||
likes: number | string;
|
||||
comments: number | string;
|
||||
}>
|
||||
>(),
|
||||
{
|
||||
avatar: '',
|
||||
name: '',
|
||||
verification: false,
|
||||
info: '',
|
||||
content: '',
|
||||
media: () => [],
|
||||
location: '',
|
||||
likes: 0,
|
||||
comments: 0,
|
||||
},
|
||||
);
|
||||
const emit = defineEmits<(e: 'detail') => void>();
|
||||
|
||||
const isLike = ref(false);
|
||||
|
||||
// 图片预览
|
||||
const previewImage = (img: string) => {
|
||||
uni.previewImage({
|
||||
urls: [img],
|
||||
});
|
||||
};
|
||||
|
||||
// 喜欢
|
||||
const handleLike = () => {
|
||||
isLike.value = true;
|
||||
};
|
||||
|
||||
// 取消喜欢
|
||||
const handleunLike = () => {
|
||||
isLike.value = false;
|
||||
};
|
||||
|
||||
// 去聊天
|
||||
const goChat = () => {
|
||||
uni.showToast({ title: '功能开发中...' });
|
||||
};
|
||||
|
||||
// 详情
|
||||
const detail = () => {
|
||||
emit('detail');
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<scroll-view
|
||||
scroll-y
|
||||
refresher-enabled
|
||||
enable-back-to-top
|
||||
refresher-background="#222"
|
||||
:refresher-triggered="refresherTriggered"
|
||||
:refresher-threshold="100"
|
||||
@refresherabort="onRefresherAbort"
|
||||
@refresherrefresh="onRefresherRefresh"
|
||||
@scrolltolower="onScrollToLower"
|
||||
@scroll="(e: any) => emit('scroll', e)"
|
||||
v-bind="attrs"
|
||||
>
|
||||
<slot />
|
||||
<uni-load-more
|
||||
:status="loadMoreStatus"
|
||||
:content-text="loadMoreContent"
|
||||
@clickLoadMore="onScrollToLower"
|
||||
/>
|
||||
<view style="height: 100rpx"></view>
|
||||
</scroll-view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref, useAttrs } from 'vue';
|
||||
|
||||
const attrs = useAttrs();
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
loadMoreStatus?: 'more' | 'loading' | 'noMore';
|
||||
}>(),
|
||||
{
|
||||
loadMoreStatus: 'noMore',
|
||||
},
|
||||
);
|
||||
const emit = defineEmits<{
|
||||
(e: 'refresh', done: () => void): void;
|
||||
(e: 'loadMore'): void;
|
||||
(e: 'scroll', event: any): void;
|
||||
}>();
|
||||
|
||||
const refresherTriggered = ref(false);
|
||||
|
||||
const loadMoreContent = reactive({
|
||||
contentdown: '正在加载...',
|
||||
contentrefresh: '正在加载...',
|
||||
contentnomore: '没有更多数据了',
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
onScrollToLower();
|
||||
});
|
||||
|
||||
// 下拉刷新中止
|
||||
const onRefresherAbort = () => {
|
||||
refresherTriggered.value = false;
|
||||
};
|
||||
|
||||
// 触发下拉刷新
|
||||
const onRefresherRefresh = () => {
|
||||
refresherTriggered.value = true;
|
||||
emit('refresh', () => {
|
||||
refresherTriggered.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
// 触发上拉加载
|
||||
const onScrollToLower = () => {
|
||||
if (props.loadMoreStatus === 'loading' || props.loadMoreStatus === 'noMore') {
|
||||
return;
|
||||
}
|
||||
emit('loadMore');
|
||||
};
|
||||
</script>
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<view
|
||||
class="flex items-center relative mx-auto border-1 border-solid border-#666 rounded-full overflow-hidden"
|
||||
class="flex items-center relative mx-auto border-1 border-solid border-#666 bg-#333 rounded-full overflow-hidden p-1"
|
||||
:style="segmentedWidth"
|
||||
>
|
||||
<view
|
||||
@@ -13,7 +13,7 @@
|
||||
<text>{{ item }}</text>
|
||||
</view>
|
||||
<div
|
||||
class="absolute left-0 top-0 h-full bg-color-theme-dark rounded-full transform duration-100"
|
||||
class="absolute h-2/3 bg-color-theme-dark rounded-full transform duration-100"
|
||||
:style="activeStyle"
|
||||
></div>
|
||||
</view>
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<view class="flex px-4 py-2">
|
||||
<image
|
||||
class="w-200rpx h-300rpx mr-3 rounded-2 bg-#777"
|
||||
:src="member.memberAvatar"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<view class="flex-1">
|
||||
<view class="flex justify-between items-center">
|
||||
<text class="text-size-base">{{ member.memberNickname }}</text>
|
||||
<text class="py-1 px-2 rounded-full text-xs bg-color-theme-dark">{{ '在线' }}</text>
|
||||
</view>
|
||||
<view class="mt-2 inline-flex px-2 py-1 text-xs c-black rounded-1 bg-color-theme-dark">
|
||||
<wd-icon name="discount-filled" size="16px" color="#000"></wd-icon>
|
||||
<text>真人认证</text>
|
||||
</view>
|
||||
<view class="mt-2 flex flex-wrap gap-3">
|
||||
<text class="bg-#333 text-color-theme-dark text-xs px-2 py-1 rounded-1">
|
||||
{{ '未知性别' }}·{{ member.memberAge }}岁
|
||||
</text>
|
||||
<text class="bg-#333 text-color-theme-dark text-xs px-2 py-1 rounded-1">
|
||||
{{ member.memberHeight }}cm
|
||||
</text>
|
||||
<text class="bg-#333 text-color-theme-dark text-xs px-2 py-1 rounded-1">
|
||||
{{ member.memberWeight }}kg
|
||||
</text>
|
||||
<text class="bg-#333 text-color-theme-dark text-xs px-2 py-1 rounded-1">
|
||||
{{ member.memberOcc }}
|
||||
</text>
|
||||
<text class="bg-#333 text-color-theme-dark text-xs px-2 py-1 rounded-1">
|
||||
{{ data.issueCity }}km
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
const props = defineProps<{
|
||||
data?: any;
|
||||
}>();
|
||||
|
||||
const member = computed(() => props.data.member || {});
|
||||
</script>
|
||||
@@ -9,7 +9,7 @@ export type cityItem = {
|
||||
lat?: string;
|
||||
};
|
||||
|
||||
const cityIndexList: any = [
|
||||
const useCityIndex = () => [
|
||||
{
|
||||
letter: 'A',
|
||||
data: [
|
||||
@@ -2160,4 +2160,4 @@ const cityIndexList: any = [
|
||||
},
|
||||
];
|
||||
|
||||
export default cityIndexList;
|
||||
export default useCityIndex;
|
||||
@@ -1,94 +1,56 @@
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { reactive, ref } from 'vue';
|
||||
|
||||
export default function useScroll(fetchList: (...arg: any) => Promise<any>, fetchBody: any = {}) {
|
||||
const refresherTriggered = ref(false);
|
||||
const loadMoreContent = reactive({
|
||||
contentdown: ' ',
|
||||
contentrefresh: '正在加载...',
|
||||
contentnomore: '没有更多数据了',
|
||||
});
|
||||
const loadMoreStatus = ref<'more' | 'loading' | 'noMore'>('more');
|
||||
export default function useScroll(fetch: (...arg: any) => Promise<any>, params: any = {}) {
|
||||
const listData = ref<any[]>([]);
|
||||
const pageInfo = reactive({
|
||||
const loadMoreStatus = ref<'more' | 'loading' | 'noMore'>('more');
|
||||
const pageParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
hasMore: true,
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
loadData(false);
|
||||
});
|
||||
const total = ref(0);
|
||||
|
||||
const loadData = async (isRefresh: boolean = false) => {
|
||||
try {
|
||||
if (pageInfo.pageNo === 1) {
|
||||
if (pageParams.pageNo === 1) {
|
||||
uni.showLoading({ title: '加载中...' });
|
||||
}
|
||||
if (isRefresh) {
|
||||
pageInfo.pageNo = 1;
|
||||
const { data = [] } = await fetchList({ ...pageInfo, ...fetchBody });
|
||||
pageParams.pageNo = 1;
|
||||
const { data = [] } = await fetch({ ...pageParams, ...params });
|
||||
listData.value = data.list ?? [];
|
||||
pageInfo.total = data.total;
|
||||
total.value = data.total;
|
||||
} else {
|
||||
const { data = [] } = await fetchList({ ...pageInfo, ...fetchBody });
|
||||
const { data = [] } = await fetch({ ...pageParams, ...params });
|
||||
listData.value.push(...(data.list ?? []));
|
||||
pageInfo.total = data.total;
|
||||
total.value = data.total;
|
||||
}
|
||||
pageInfo.pageNo = pageInfo.pageNo + 1;
|
||||
pageParams.pageNo = pageParams.pageNo + 1;
|
||||
|
||||
if (listData.value?.length >= pageInfo.total) {
|
||||
if (listData.value?.length >= total.value) {
|
||||
loadMoreStatus.value = 'noMore';
|
||||
} else {
|
||||
loadMoreStatus.value = 'more';
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('加载数据失败:', error);
|
||||
return false;
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
}
|
||||
};
|
||||
|
||||
// 触发下拉刷新
|
||||
const onRefresherRefresh = async () => {
|
||||
refresherTriggered.value = true;
|
||||
const success = await loadData(true);
|
||||
refresherTriggered.value = false;
|
||||
const refreshList = async (done: () => void = () => {}) => {
|
||||
await loadData(true);
|
||||
done();
|
||||
};
|
||||
|
||||
// 下拉刷新中止
|
||||
const onRefresherAbort = () => {
|
||||
console.log('下拉刷新中止');
|
||||
refresherTriggered.value = false;
|
||||
};
|
||||
|
||||
// 触发上拉加载
|
||||
const onScrollToLower = async () => {
|
||||
if (loadMoreStatus.value === 'loading' || loadMoreStatus.value === 'noMore') {
|
||||
return;
|
||||
}
|
||||
loadMoreStatus.value = 'loading';
|
||||
await loadData(false);
|
||||
};
|
||||
|
||||
// 点击加载更多
|
||||
const onClickLoadMore = () => {
|
||||
if (loadMoreStatus.value === 'more') {
|
||||
onScrollToLower();
|
||||
}
|
||||
const listLoadMore = () => {
|
||||
loadData(false);
|
||||
};
|
||||
|
||||
return {
|
||||
listData,
|
||||
refresherTriggered,
|
||||
loadMoreContent,
|
||||
loadMoreStatus,
|
||||
onRefresherRefresh,
|
||||
onRefresherAbort,
|
||||
onScrollToLower,
|
||||
onClickLoadMore,
|
||||
refreshList,
|
||||
listLoadMore,
|
||||
};
|
||||
}
|
||||
@@ -54,6 +54,12 @@ export default {
|
||||
color: '#ffcd32',
|
||||
},
|
||||
],
|
||||
[
|
||||
'text-color-theme-dark',
|
||||
{
|
||||
color: 'rgba(255, 205, 49, 0.8)',
|
||||
},
|
||||
],
|
||||
[
|
||||
'bg-color',
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user