feat:查看微信大修改

feat:增加开通会员记录
This commit is contained in:
dzc committed 2025-12-15 15:40:00 +08:00
1 parent d7550e48b0
commit 656afd520e
12 files changed
+493 -379

No files matched your search

+2 -2
View File
@@ -6,8 +6,8 @@ SHOPRO_API_PATH=/app-api
# 后端接口 - 测试环境(通过 process.env.NODE_ENV == development)
# SHOPRO_DEV_BASE_URL=http://127.0.0.1:48083
SHOPRO_DEV_BASE_URL = https://chatapi.zianxin.com
# SHOPRO_DEV_BASE_URL=https://rj4jv5rwqs.by.takin.cc
# SHOPRO_DEV_BASE_URL = https://chatapi.zianxin.com
SHOPRO_DEV_BASE_URL=https://rj4jv5rwqs.by.takin.cc
# 后端接口 - 正式环境(通过 process.env.NODE_ENV != development)
SHOPRO_BASE_URL=https://chatapi.zianxin.com
+8 -1
View File
@@ -265,6 +265,13 @@
"navigationStyle": "custom"
}
},
{
"path": "apply-vip-record",
"style": {
"navigationBarTitleText": "历史记录",
"navigationStyle": "custom"
}
},
{
"path": "apply-vip",
"style": {
@@ -1039,4 +1046,4 @@
]
// #endif
}
}
}
+355 -356
View File
@@ -4,20 +4,15 @@
<template #left>
<uni-icons type="back" size="30" color="#D29E52" @click="back"></uni-icons>
<view class="flex items-center" :style="navUserInfoStyle">
<image
class="size-70rpx bg-#333 rounded-full mr-1"
:src="userDetail.member?.memberAvatar"
mode="aspectFill"
/>
<image class="size-70rpx bg-#333 rounded-full mr-1" :src="userDetail.member?.memberAvatar"
mode="aspectFill" />
<text class="truncate text-sm">{{ userDetail.member?.memberNickname }}</text>
</view>
</template>
<template #right>
<view class="flex items-center">
<view
v-if="userDetail.member?.memberCity || userDetail.distance"
class="py-1 px-2 text-xs bg-color-theme-dark rounded-full mr-3"
>
<view v-if="userDetail.member?.memberCity || userDetail.distance"
class="py-1 px-2 text-xs bg-color-theme-dark rounded-full mr-3">
{{ userDetail.member.memberCity ? userDetail.member.memberCity + ' · ' : '' }}
{{ userDetail.distance ? userDetail.distance.toFixed(2) + 'km' : '' }}
</view>
@@ -26,65 +21,36 @@
</template>
</wd-navbar>
<scroll-list
v-if="userDetail?.member?.memberId"
style="height: calc(100dvh - 88px)"
:loadMoreStatus="loadMoreStatus"
@refresh="refreshList"
@loadMore="listLoadMore"
@scroll="onScroll"
>
<scroll-list v-if="userDetail?.member?.memberId" style="height: calc(100dvh - 88px)"
:loadMoreStatus="loadMoreStatus" @refresh="refreshList" @loadMore="listLoadMore" @scroll="onScroll">
<view class="w-full h-600rpx relative">
<image
class="w-full h-full absolute inset-0"
:src="userDetail.member.memberAvatar"
mode="aspectFill"
/>
<view
class="absolute bottom-100rpx left-0 right-0 text-xs flex flex-col items-center z-100 w-full"
>
<image
class="text-center size-150rpx rounded-full bg-#333 mb-20rpx"
:src="userDetail.member.memberAvatar"
mode="aspectFill"
/>
<image class="w-full h-full absolute inset-0" :src="userDetail.member.memberAvatar" mode="aspectFill" />
<view class="absolute bottom-100rpx left-0 right-0 text-xs flex flex-col items-center z-100 w-full">
<image class="text-center size-150rpx rounded-full bg-#333 mb-20rpx" :src="userDetail.member.memberAvatar"
mode="aspectFill" />
<view class="text-base mb-20rpx">{{ userDetail.member?.memberNickname }}</view>
<view
v-for="(item, index) in userDetail.memberTagList"
:key="index"
class="mb-20rpx inline-flex px-2 py-1 text-xs c-black rounded-1 bg-color-theme-dark"
>
<view v-for="(item, index) in userDetail.memberTagList" :key="index"
class="mb-20rpx 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>{{ item.tagTitle }}</text>
</view>
<view class="flex flex-wrap justify-center mb-20rpx">
<text
v-if="userDetail.member.memberSex || userDetail.member.memberAge"
class="px-2 py-1 rounded-1 mr-2 bg-#222 text-color-theme-dark"
>
<text v-if="userDetail.member.memberSex || userDetail.member.memberAge"
class="px-2 py-1 rounded-1 mr-2 bg-#222 text-color-theme-dark">
<text v-if="userDetail.member.memberSex">
{{ getGender(userDetail.member.memberSex) }}
</text>
<text v-if="userDetail.member.memberSex && userDetail.member.memberAge">·</text>
<text v-if="userDetail.member.memberAge">{{ userDetail.member.memberAge }}岁</text>
</text>
<text
v-if="userDetail.member.memberHeight"
class="px-2 py-1 rounded-1 mr-2 bg-#222 text-color-theme-dark"
>
<text v-if="userDetail.member.memberHeight" class="px-2 py-1 rounded-1 mr-2 bg-#222 text-color-theme-dark">
{{ userDetail.member.memberHeight }}cm
</text>
<text
v-if="userDetail.member.memberWeight"
class="px-2 py-1 rounded-1 mr-2 bg-#222 text-color-theme-dark"
>
<text v-if="userDetail.member.memberWeight" class="px-2 py-1 rounded-1 mr-2 bg-#222 text-color-theme-dark">
{{ userDetail.member.memberWeight }}kg
</text>
<text
v-if="userDetail.member.memberOcc"
class="px-2 py-1 rounded-1 mr-2 bg-#222 text-color-theme-dark"
>
<text v-if="userDetail.member.memberOcc" class="px-2 py-1 rounded-1 mr-2 bg-#222 text-color-theme-dark">
{{ userDetail.member.memberOcc }}
</text>
</view>
@@ -94,50 +60,37 @@
</view>
<view class="absolute z-10 top-0 left-0 size-full bg-#33333333" :style="filterStyle"></view>
</view>
<view v-if="userDetail.member.wechatNum" class="m-4">
<view class="m-4">
<view class="my-2 text-size-base">查看微信</view>
<view
v-if="!userWechatInfo.wechatNum"
class="bg-color-theme rounded-1 flex justify-between items-center p-2"
>
<view class="bg-color-theme rounded-1 flex justify-between items-center p-2">
<view class="flex-col">
<view class="flex items-center">
<image class="size-44rpx mr-2" src="@/static/weixin-black.png" mode="aspectFill" />
<text class="text-black">{{ userDetail.member.wechatNum || '*************' }}</text>
</view>
<view class="text-xs c-black tracking-0.2">
<view v-if="!userDetail?.userOperationStatus?.isLookWechat" class="text-xs c-black tracking-0.2">
<text>成为</text>
<text class="text-base font-bold font-italic"> VIP </text>
<text>免费解锁</text>
</view>
<view v-else>
<text class="text-black text-xs">已解锁对方微信</text>
</view>
</view>
<view class="rounded-1 px-4 py-1 bg-#333 active:bg-#222" @click="unlockWeChat">
<view v-if="!userDetail?.userOperationStatus?.isLookWechat" class="rounded-1 px-4 py-1 bg-#333 active:bg-#222"
@click="doWeChatBtn">
解锁
</view>
</view>
<view v-else class="bg-color-theme rounded-1 flex justify-between items-center p-2">
<view class="flex items-center">
<image class="size-44rpx mr-2" src="@/static/weixin-black.png" mode="aspectFill" />
<text class="text-black">{{ userWechatInfo.wechatNum }}</text>
</view>
<view class="rounded-1 px-4 py-1 bg-#333 active:bg-#222" @click="copyWechatNum">
复制
<view v-else class="rounded-1 px-4 py-1 bg-#333 active:bg-#222" @click="doWeChatBtn">
查看
</view>
</view>
</view>
<view class="m-4">
<view class="my-2 text-size-base">相册</view>
<image
v-if="photoListUrls.length"
class="size-140rpx rounded-1 mr-2 mb-1"
v-for="(item, index) in photoListUrls"
:key="index"
:src="item"
mode="aspectFill"
@click="previewPhoto(index)"
/>
<image v-if="photoListUrls.length" class="size-140rpx rounded-1 mr-2 mb-1"
v-for="(item, index) in photoListUrls" :key="index" :src="item" mode="aspectFill"
@click="previewPhoto(index)" />
<view class="text-center c-#949494" v-else>相册暂无照片</view>
</view>
@@ -168,323 +121,369 @@
<view v-if="isRefreshing" 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"
/>
<wd-skeleton :custom-style="{ width: '100%', marginLeft: '12px' }" animation="flashed" theme="paragraph" />
</view>
<moment-card
v-else-if="listData.length"
v-for="(item, index) in listData"
:data="item"
:show-chat="false"
:key="index"
/>
<moment-card v-else-if="listData.length" v-for="(item, index) in listData" :data="item" :show-chat="false"
:key="index" />
<wd-status-tip v-else image="content" tip="暂无内容" />
</scroll-list>
<view class="fixed bottom-100 left-0 right-0 flex justify-around bg-transparent">
<view
class="text-base py-2 px-10 rounded-full bg-color-theme-dark flex gap-2"
@click="goChat"
>
<view class="text-base py-2 px-10 rounded-full bg-color-theme-dark flex gap-2" @click="goChat">
<uni-icons type="chat" size="24" color="#B5B4BC"></uni-icons>
<text>私聊</text>
</view>
<view
class="text-base py-2 px-10 rounded-full bg-white c-black flex gap-2"
@click="handleLike"
>
<uni-icons
v-if="userDetail.userOperationStatus?.isLike"
type="heart-filled"
size="24"
color="#D29E52"
/>
<view class="text-base py-2 px-10 rounded-full bg-white c-black flex gap-2" @click="handleLike">
<uni-icons v-if="userDetail.userOperationStatus?.isLike" type="heart-filled" size="24" color="#D29E52" />
<uni-icons v-else type="heart" size="24" color="#B5B4BC"></uni-icons>
<text>喜欢</text>
</view>
</view>
<wd-action-sheet
v-model="actionShow"
:actions="[{ name: '拉黑' }, { name: '举报' }]"
@select="actionSelect"
cancel-text="取消"
:z-index="100"
/>
<wd-message-box />
<wd-action-sheet v-model="actionShow" :actions="[{ name: '拉黑' }, { name: '举报' }]" @select="actionSelect"
cancel-text="取消" :z-index="100" />
<wd-message-box selector="operateMessage" />
<wd-popup custom-class="custom-wechat-popup" :z-index="999" v-model="visibleWechat">
<view class="w-full overflow-hidden p-y-50rpx bg-#f9c26f">
<view v-if="!userDetail?.userOperationStatus?.isLookWechat" class="flex-col justify-center items-center">
<image class="size-150rpx bg-#333 rounded-full mr-1" :src="userDetail.member?.memberAvatar"
mode="aspectFill" />
<view class="inline-flex items-center justify-center bg-color-theme-dark m-t-30rpx p-x-10 p-y-1 rounded-full">
<image class="size-44rpx mr-2" src="@/static/weixin-black.png" mode="aspectFill" />
<text class="text-black text-xs">{{ userDetail.member.wechatNum || '*************' }}</text>
</view>
<view class="flex justify-center items-center m-t-30rpx text-color-theme">
<text class="iconfont icon-weixin" />
</view>
<text class="text-color-theme text-xs m-t-30rpx">今日vip特权已使用4/10次</text>
<view class="flex justify-center items-center bg-color-theme-dark m-t-30rpx w-full p-x-10 p-y-2 rounded-full"
@tap="doSubmitUnlockWechat">
<text class="text-black text-xs">使用VIP特权免费解锁</text>
</view>
</view>
<view class="flex-col justify-center items-center" v-else>
<view class="inline-flex items-center justify-center">
<image class="size-44rpx mr-2" src="@/static/weixin-black.png" mode="aspectFill" />
<text class="text-black text-xs">{{ userDetail.member.wechatNum || '*************' }}</text>
</view>
<view class="flex-col justify-center items-center m-t-15rpx text-black text-xs">
<view>解锁微信只能展示24小时</view>
<view>添加备注"荷塘月色App"会快速通过哟</view>
</view>
<view class="m-t-30rpx p-x-10 p-y-1.5 bg-#333 text-xs rounded-full" @tap="copyWechatNum">复制微信号</view>
<view class="m-t-30rpx text-xs">
<text>搜索不到微信?点击【</text>
<text class="underline underline-1 underline-solid">立即举报</text>
<text>】退还次数</text>
</view>
</view>
</view>
</wd-popup>
</wd-config-provider>
</template>
<script setup lang="ts">
// @ts-nocheck
import { ref, computed, getCurrentInstance, reactive, onMounted } 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 { onHide, onUnload, onLoad } from '@dcloudio/uni-app';
import { getGender } from '@/sheep/util/index';
import sheep from '@/sheep';
import useConfigStore from '@/chat-store/configStore.js';
import useChatStore from '@/chat-store/chatStore.js';
import useFriendStore from '@/chat-store/friendStore.js';
import request from '@/common/request';
import { formatDate } from '@/sheep/helper/utils';
import { useMessage } from '@/uni_modules/wot-design-uni';
// @ts-nocheck
import { ref, computed, getCurrentInstance, reactive, onMounted } 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 { onHide, onUnload, onLoad } from '@dcloudio/uni-app';
import { getGender } from '@/sheep/util/index';
import sheep from '@/sheep';
import useConfigStore from '@/chat-store/configStore.js';
import useChatStore from '@/chat-store/chatStore.js';
import useFriendStore from '@/chat-store/friendStore.js';
import request from '@/common/request';
import { formatDate } from '@/sheep/helper/utils';
import { useMessage } from '@/uni_modules/wot-design-uni';
const message = useMessage();
const operateMessage = useMessage('operateMessage');
const userCity = computed(() => sheep.$store('user').userCity);
const userInfo = computed(() => sheep.$store('user').userInfo);
const userCity = computed(() => sheep.$store('user').userCity);
const userInfo = computed(() => sheep.$store('user').userInfo);
const scrollTop = ref(0);
const userDetail = ref<any>({}); // 用户详情
const actionShow = ref(false);
// 朋友圈列表参数
const params = reactive({
scene: 'DYNAMIC_RECOMMEND',
province: '',
city: userCity.value.t,
memberId: '',
});
// 评价
const rating = reactive({
scoreSc: 0, // 身材评分
scoreNx: 0, // 耐心评分
scoreSk: 0, // 爽快评分
scoreYq: 0, // 有趣评分
});
// 浏览记录参数
const viewRecord = reactive({
bizType: '',
bizId: '',
viewStartTime: new Date().getTime(),
viewEndTime: '',
});
// 用户微信信息
const userWechatInfo = reactive({
wechatNum: '',
wechatQrCode: '',
});
const scrollTop = ref(0);
// 用户详情
const userDetail = ref<any>({});
// 解锁微信次数
const lookWechatDetail = ref<any>({});
const actionShow = ref(false);
const visibleWechat = ref(false)
// 朋友圈列表参数
const params = reactive({
scene: 'DYNAMIC_RECOMMEND',
province: '',
city: userCity.value.t,
memberId: '',
});
// 评价
const rating = reactive({
scoreSc: 0, // 身材评分
scoreNx: 0, // 耐心评分
scoreSk: 0, // 爽快评分
scoreYq: 0, // 有趣评分
});
// 浏览记录参数
const viewRecord = reactive({
bizType: '',
bizId: '',
viewStartTime: new Date().getTime(),
viewEndTime: '',
});
// 用户微信信息
const userWechatInfo = reactive({
wechatNum: '',
wechatQrCode: '',
});
const photoListUrls = computed(
() =>
userDetail.value.memberPhotoList
?.filter((i) => i.resourceType === 'IMAGE')
.map((item) => item.address) || [],
);
const photoListUrls = computed(
() =>
userDetail.value.memberPhotoList
?.filter((i) => i.resourceType === 'IMAGE')
.map((item) => item.address) || [],
);
onLoad(async (options: any) => {
const { memberId } = options;
if (!memberId) return uni.showToast({ title: '参数错误', icon: 'none' });
params.memberId = memberId;
viewRecord.bizId = memberId;
await getDetail();
});
onLoad(async (options: any) => {
const { memberId } = options;
if (!memberId) return uni.showToast({ title: '参数错误', icon: 'none' });
params.memberId = memberId;
viewRecord.bizId = memberId;
await getDetail();
await lookWechatCount()
});
// 获取用户详情
const getDetail = async () => {
const { data = null } = await RecentApi.getRecentDetail({ id: params.memberId });
userDetail.value = data ?? {};
// 获取用户详情
const getDetail = async () => {
const { data = null } = await RecentApi.getRecentDetail({ id: params.memberId });
userDetail.value = data ?? {};
if (data.member && data.member.wechatNum) {
userWechatInfo.wechatNum = data.member.wechatNum;
}
};
// 查询解锁微信次数
const lookWechatCount = async () => {
const { data = null } = await RecentApi.lookWechatCount();
lookWechatDetail.value = data ?? {};
}
onMounted(() => {
refreshList();
});
const { isRefreshing, listData, loadMoreStatus, refreshList, listLoadMore } = useScroll(
RecentApi.quickPage,
params,
);
const filterStyle = computed(() => {
let blur = 0;
const scrollY = scrollTop.value;
if (scrollY >= 0) {
blur = Math.min(1, scrollY / 300) * 10;
}
return {
backdropFilter: `blur(${blur}px)`,
};
onMounted(() => {
refreshList();
});
const { isRefreshing, listData, loadMoreStatus, refreshList, listLoadMore } = useScroll(
RecentApi.quickPage,
params,
);
const filterStyle = computed(() => {
let blur = 0;
const scrollY = scrollTop.value;
if (scrollY >= 0) {
blur = Math.min(1, scrollY / 300) * 10;
}
return {
backdropFilter: `blur(${blur}px)`,
};
});
const navUserInfoStyle = computed(() => {
let opacity = 1;
const scrollY = scrollTop.value;
if (scrollY >= 0) {
opacity = Math.min(1, scrollY / 300 < 0.4 ? 0 : scrollY / 300);
}
return {
opacity,
};
});
function back() {
uni.navigateBack();
});
const navUserInfoStyle = computed(() => {
let opacity = 1;
const scrollY = scrollTop.value;
if (scrollY >= 0) {
opacity = Math.min(1, scrollY / 300 < 0.4 ? 0 : scrollY / 300);
}
return {
opacity,
};
});
function onScroll(e: any) {
scrollTop.value = e.detail.scrollTop;
function back() {
uni.navigateBack();
}
function onScroll(e: any) {
scrollTop.value = e.detail.scrollTop;
}
// 解锁微信
const doWeChatBtn = async () => {
if (!params.memberId) return uni.showToast({ title: '用户id不存在', icon: 'none' });
const vip = userInfo.value?.memberVip.vip;
// 如果不是vip
if (!vip) {
operateMessage
.confirm({
title: '获取VIP特权',
msg: '请先开通VIP会员',
confirmButtonText: '获取会员',
zIndex: 9999,
})
.then(() => {
uni.navigateTo({
url: '/pages/profile/apply-vip',
});
})
.catch(() => { });
return;
}
visibleWechat.value = true
};
// 解锁微信
const unlockWeChat = async () => {
if (!params.memberId) return uni.showToast({ title: '用户id不存在', icon: 'none' });
const vip = userInfo.value?.memberVip.vip;
// 如果不是vip
if (!vip) {
message
.confirm({
title: '获取VIP特权',
msg: '请先开通VIP会员',
confirmButtonText: '获取会员',
zIndex: 9999,
})
.then(() => {
uni.navigateTo({
url: '/pages/profile/apply-vip',
});
})
.catch(() => {});
return;
}
// 执行解锁微信
const doSubmitUnlockWechat = async () => {
try {
const { code, data } = await RecentApi.unlockWeChat({ memberId: params.memberId });
if (code === 0) {
uni.showToast({ title: '解锁成功', icon: 'none' });
Object.assign(userWechatInfo, data);
getDetail()
}
};
// 复制微信号
const copyWechatNum = () => {
uni.setClipboardData({
data: userWechatInfo.wechatNum,
showToast: false,
success: () => {
uni.showToast({ title: '微信号已复制', icon: 'success' });
},
});
};
// 相册预览
const previewPhoto = (current: number) => {
uni.previewImage({
current,
urls: photoListUrls.value,
indicator: 'number',
});
};
// 私聊
const goChat = async () => {
if (!userDetail.value.memberId) return uni.showToast({ title: '用户不存在' });
const { code } = await RecentApi.chatAddFriend({
friendUserId: userDetail.value.memberId,
});
if (code !== 0) return uni.showToast({ title: '好友添加失败', icon: 'error' });
const friendStore = useFriendStore();
const configStore = useConfigStore();
const chatStore = useChatStore();
request({
url: '/user/find/' + userDetail.value.memberId,
method: 'GET',
}).then((user: any) => {
let friendInfo = user;
const friend = {
id: friendInfo.id,
nickName: friendInfo.nickName,
headImage: friendInfo.headImageThumb,
online: friendInfo.online,
deleted: false,
};
friendStore.addFriend(friend);
const chat: any = {
type: 'PRIVATE',
targetId: friendInfo.id,
showName: friendInfo.nickName,
headImage: friendInfo.headImageThumb,
isDnd: friendInfo.isDnd,
};
chatStore.openChat(chat);
const chatIdx = chatStore.findChatIdx(chat);
// 防止初始化期间进入会话导致的消息不刷新
if (!configStore.appInit || chatStore.loading) {
uni.showToast({
title: '正在初始化页面,请稍后...',
icon: 'none',
});
return;
}
uni.navigateTo({ url: '/pages/message/chat-box?chatIdx=' + chatIdx });
});
};
// 拉黑 举报
async function actionSelect({ item, index }) {
switch (index) {
case 0:
const { code } = await RecentApi.recentOperate({
memberId: userDetail.value.member.memberId,
action: 'MEMBER_SHIELD',
});
if (code === 0) {
uni.showToast({ title: '拉黑成功', icon: 'none' });
}
break;
case 1:
uni.navigateTo({ url: '/pages/home/report?memberId=' + userDetail.value.member.memberId });
}
} catch (error) {
console.log("|执行解锁微信|,意外的错误:error", error);
}
}
// 喜欢
const handleLike = async () => {
const { code } = await RecentApi.recentOperate({
memberId: userDetail.value.member.memberId,
action: 'MEMBER_COLLECT',
});
if (code !== 0) return;
await getDetail();
};
// 复制微信号
const copyWechatNum = () => {
console.log("userWechatInfo:", userWechatInfo);
// 评分
// const rate = async () => {
// await RecentApi.recentOperate({
// memberId: userDetail.value.member.memberId,
// action: 'MEMBER_RATING',
// ...rating,
// });
// };
const instance: any = getCurrentInstance()?.proxy;
const eventChannel = instance.getOpenerEventChannel();
eventChannel.on('viewRecordType', function (bizType: 'CLASSIFY' | 'RECENT' | 'USER') {
viewRecord.bizType = bizType;
uni.setClipboardData({
data: userWechatInfo.wechatNum,
showToast: false,
success: () => {
uni.showToast({ title: '微信号已复制', icon: 'success' });
visibleWechat.value = false
},
});
};
// 添加用户详情页面的查看和访问记录
const createViewRecord = () => {
if (!viewRecord.bizType || !viewRecord.bizId) return;
RecentApi.createViewRecord({
...viewRecord,
viewEndTime: new Date().getTime(),
});
};
onHide(() => {
createViewRecord();
// 相册预览
const previewPhoto = (current: number) => {
uni.previewImage({
current,
urls: photoListUrls.value,
indicator: 'number',
});
onUnload(() => {
createViewRecord();
};
// 私聊
const goChat = async () => {
if (!userDetail.value.memberId) return uni.showToast({ title: '用户不存在' });
const { code } = await RecentApi.chatAddFriend({
friendUserId: userDetail.value.memberId,
});
if (code !== 0) return uni.showToast({ title: '好友添加失败', icon: 'error' });
const friendStore = useFriendStore();
const configStore = useConfigStore();
const chatStore = useChatStore();
request({
url: '/user/find/' + userDetail.value.memberId,
method: 'GET',
}).then((user: any) => {
let friendInfo = user;
const friend = {
id: friendInfo.id,
nickName: friendInfo.nickName,
headImage: friendInfo.headImageThumb,
online: friendInfo.online,
deleted: false,
};
friendStore.addFriend(friend);
const chat: any = {
type: 'PRIVATE',
targetId: friendInfo.id,
showName: friendInfo.nickName,
headImage: friendInfo.headImageThumb,
isDnd: friendInfo.isDnd,
};
chatStore.openChat(chat);
const chatIdx = chatStore.findChatIdx(chat);
// 防止初始化期间进入会话导致的消息不刷新
if (!configStore.appInit || chatStore.loading) {
uni.showToast({
title: '正在初始化页面,请稍后...',
icon: 'none',
});
return;
}
uni.navigateTo({ url: '/pages/message/chat-box?chatIdx=' + chatIdx });
});
};
// 拉黑 举报
async function actionSelect({ item, index }) {
switch (index) {
case 0:
const { code } = await RecentApi.recentOperate({
memberId: userDetail.value.member.memberId,
action: 'MEMBER_SHIELD',
});
if (code === 0) {
uni.showToast({ title: '拉黑成功', icon: 'none' });
}
break;
case 1:
uni.navigateTo({ url: '/pages/home/report?memberId=' + userDetail.value.member.memberId });
}
}
// 喜欢
const handleLike = async () => {
const { code } = await RecentApi.recentOperate({
memberId: userDetail.value.member.memberId,
action: 'MEMBER_COLLECT',
});
if (code !== 0) return;
await getDetail();
};
// 评分
// const rate = async () => {
// await RecentApi.recentOperate({
// memberId: userDetail.value.member.memberId,
// action: 'MEMBER_RATING',
// ...rating,
// });
// };
const instance: any = getCurrentInstance()?.proxy;
const eventChannel = instance.getOpenerEventChannel();
eventChannel.on('viewRecordType', function (bizType: 'CLASSIFY' | 'RECENT' | 'USER') {
viewRecord.bizType = bizType;
});
// 添加用户详情页面的查看和访问记录
const createViewRecord = () => {
if (!viewRecord.bizType || !viewRecord.bizId) return;
RecentApi.createViewRecord({
...viewRecord,
viewEndTime: new Date().getTime(),
});
};
onHide(() => {
createViewRecord();
});
onUnload(() => {
createViewRecord();
});
</script>
<style lang="scss">
.custom-wechat-popup {
width: 70% !important;
padding: 0 !important;
margin: 0 !important;
border-radius: 32rpx !important;
}
</style>
+56
View File
@@ -0,0 +1,56 @@
<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="#D29E52"></uni-icons>
</navigator>
</template>
</wd-navbar>
<scroll-list style="height: calc(100dvh - 44px - 50px)" :loadMoreStatus="loadMoreStatus" @refresh="refreshList"
@loadMore="listLoadMore">
<view class="flex-col justify-center card-thin mx-20rpx px-20rpx py-18rpx mb-15rpx"
v-for="(v, i) in listData" :key="v.id">
<view class="text-xs break-all">
<wd-tag size="30rpx" custom-class="space">
<view class="p-0.25">开通会员</view>
</wd-tag>
<text class="text-xs m-l-10rpx">支付</text>
<text class="text-xs text-color-theme">
{{ fen2yuan(v.payPrice) }}元
</text>
<text class="text-xs">开通</text>
<text class="text-xs text-color-theme">{{ v.vipTitle }}会员</text>
<text>有效期至</text>
<text class="text-xs text-color-theme">
{{ formatDate(v.endTime) }}({{ v.vipDuration }}天)
</text>
</view>
<view class="flex justify-end m-t-10rpx text-xs">
<text>支付时间:{{ formatDate(v.payTime) }}</text>
</view>
</view>
</scroll-list>
</wd-config-provider>
</template>
<script setup lang="ts">
import { onLoad, onShow } from '@dcloudio/uni-app';
// @ts-ignore
import { fen2yuan, fen2yuanSimple } from '@/sheep/hooks/useGoods';
// @ts-ignore
import { formatDate } from '@/sheep/helper/utils';
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, loadMoreStatus, refreshList, listLoadMore } = useScroll(
RecentApi.openTypeUserPage,
);
onShow(() => {
refreshList();
});
</script>
+17 -4
View File
@@ -5,7 +5,23 @@
<navigator open-type="navigateBack" hover-class="navigator-hover">
<uni-icons type="back" size="30" color="#D29E52"></uni-icons>
</navigator>
<!-- #ifdef MP-WEIXIN -->
<navigator url="/pages/profile/apply-vip-record" 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 text-sm">
历史记录
</view>
</navigator>
<!-- #endif -->
</template>
<!-- #ifndef MP-WEIXIN -->
<template #right>
<navigator url="/pages/profile/apply-vip-record" 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 text-sm">
历史记录
</view>
</navigator>
</template>
<!-- #endif -->
</wd-navbar>
<scroll-view style="height: calc(100dvh - 88px)" scroll-y>
@@ -219,9 +235,6 @@ const handleOpenVip = () => {
uni.showToast({ title: `不支持${payMethodItem.title}支付`, icon: 'none' });
return;
}
jumpToWechatPage();
return;
messageBox
.confirm({
msg: '确认开通?',
@@ -250,7 +263,7 @@ const disposeWechatPay = async (openTypeId: any) => {
uni.showToast({ title: '创建订单失败', icon: 'none' });
throw new Error('创建订单失败');
}
sheep.$platform.pay(payMethod.value, 'recharge', data);
await sheep.$platform.pay(payMethod.value, 'recharge', data);
// 更新用户信息
$store('user').getInfo();
uni.showToast({ title: '支付成功', icon: 'success' });
+5 -3
View File
@@ -18,7 +18,7 @@
</wd-tag>
<view class="ml-10rpx flex items-center">
<text class="text-xs">支付</text>
<text class="flex-1 text-xs text-color-theme text-center">{{ fen2yuan(v.payPrice) }}元</text>
<text class="text-xs text-color-theme text-center">{{ fen2yuan(v.payPrice) }}元</text>
<text class="text-xs">获得</text>
<text class="flex-1 text-xs text-color-theme text-center">{{ fen2yuanSimple(v.totalPrice) }}</text>
<text>砖石</text>
@@ -31,9 +31,11 @@
</template>
<script setup lang="ts">
import { onMounted } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app';
// @ts-ignore
import { fen2yuan, fen2yuanSimple } from '@/sheep/hooks/useGoods';
// @ts-ignore
import { formatDate } from '@/sheep/helper/utils';
import ScrollList from '@/sheep/components/scroll-list/scroll-list.vue';
@@ -44,7 +46,7 @@ const { listData, loadMoreStatus, refreshList, listLoadMore } = useScroll(
RecentApi.walletRechargeRecord,
);
onMounted(() => {
onShow(() => {
refreshList();
});
</script>
+2 -1
View File
@@ -121,7 +121,6 @@ const rechargePackag = ref<{ id: number; name: string; payPrice: number; bonusPr
const userWallet = computed(() => sheep.$store('user').userWallet);
onLoad((params) => {
console.log("onLoad:", params);
if (params) {
if (params.packageId && params.payMethod) {
payMethod.value = params.payMethod;
@@ -133,6 +132,8 @@ onLoad((params) => {
onShow(async () => {
const { data } = await RecentApi.getWalletRechargePackage();
rechargePackag.value = data ?? [];
// 查询钱包余额
getWallet();
});
const getWallet = () => {
+7 -6
View File
@@ -68,15 +68,16 @@
<view class="font-900 font-italic text-xl">VIP</view>
<view class="flex items-center">
<text class="text-xs">尊享vip免费特权</text>
<navigator v-if="!userInfo.memberVip?.vip" url="/pages/profile/apply-vip" open-type="navigate"
hover-class="navigator-hover">
<text class="ml-4 px-4 py-1 rounded-full text-24rpx bg-color-theme text-black">
<navigator url="/pages/profile/apply-vip" open-type="navigate" hover-class="navigator-hover">
<text v-if="!userInfo.memberVip?.vip"
class="ml-4 px-4 py-1 rounded-full text-24rpx bg-color-theme text-black">
立即开通
</text>
<text v-else class="ml-4 px-2 py-1 rounded-1 text-24rpx bg-color-theme text-black">
VIP 开通成功
</text>
</navigator>
<text v-else class="ml-4 px-2 py-1 rounded-1 text-24rpx bg-color-theme text-black">
VIP 开通成功
</text>
</view>
</view>
+9 -2
View File
@@ -14,10 +14,17 @@
<image :src="userInfo.avatar" class="size-50px rounded-full bg-#333 border border-amber border-solid"
mode="aspectFill" />
<view v-if="isLogin" class="flex-1 ml-20rpx">
<view class="mb-1 text-base">{{ userInfo.nickname }}</view>
<view class="mb-1 text-base">
<text>{{ userInfo.nickname }}</text>
<image class="size-24rpx ml-2" :src="userGenderImageSrc" mode="scaleToFill" />
</view>
<view class="mb-2 text-xs text-#ffffff80 flex items-center">
<text>ID: {{ userInfo.id }}</text>
<image class="size-24rpx ml-4" :src="userGenderImageSrc" mode="scaleToFill" />
<view v-if="userInfo.memberVip?.vip"
class="text-20rpx ml-2 flex-row-center bg-color-theme-dark px-1 rounded-1">
<uni-icons type="vip-filled" size="14" />
<text class="text-color-dark ml-1">VIP</text>
</view>
</view>
</view>
</view>
+23
View File
@@ -223,6 +223,18 @@ const RecentApi = {
},
});
},
// 开通会员记录
openTypeUserPage: (data: any) => {
return request({
url: '/member/open-type-user/page',
method: 'GET',
data,
custom: {
showLoading: true,
loadingMsg: '加载中',
},
});
},
// 提交反馈
feedback: (data: any) => {
return request({
@@ -415,6 +427,17 @@ const RecentApi = {
});
},
// 解锁微信信息
lookWechatCount: (data: any) => {
return request({
url: '/member/recent/look-wechat-count',
method: 'GET',
data,
custom: {
showLoading: false,
},
});
},
// 解锁微信信息
unlockWeChat: (data: any) => {
return request({
url: '/member/recent/look-wechat',
+2 -1
View File
@@ -377,7 +377,8 @@ export function getPayMethods(channels) {
// 支付结果跳转,success:成功,fail:失败
export function goPayResult(id, orderType, resultType) {
const url = `/pages/pay/result?id=${id}&orderType=${orderType}&payState=${resultType}`;
// const url = `/pages/pay/result?id=${id}&orderType=${orderType}&payState=${resultType}`;
const url = `/pages/profile/pay-result?id=${id}&orderType=${orderType}&payState=${resultType}`;
uni.redirectTo({ url: url })
}
+7 -3
View File
@@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 5079650 */
src: url('//at.alicdn.com/t/c/font_5079650_q7e82zvyi4j.woff2?t=1764739737667') format('woff2'),
url('//at.alicdn.com/t/c/font_5079650_q7e82zvyi4j.woff?t=1764739737667') format('woff'),
url('//at.alicdn.com/t/c/font_5079650_q7e82zvyi4j.ttf?t=1764739737667') format('truetype');
src: url('//at.alicdn.com/t/c/font_5079650_0eztc033f38b.woff2?t=1765772507380') format('woff2'),
url('//at.alicdn.com/t/c/font_5079650_0eztc033f38b.woff?t=1765772507380') format('woff'),
url('//at.alicdn.com/t/c/font_5079650_0eztc033f38b.ttf?t=1765772507380') format('truetype');
}
.iconfont {
@@ -13,6 +13,10 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-weixin:before {
content: "\e63d";
}
.icon-huiyuan:before {
content: "\e67e";
}