# Conflicts:
#	src/pages/profile/apply-vip.vue
This commit is contained in:
dzc committed 2025-12-12 16:55:45 +08:00
commit 626a20228a
4 files changed
+336 -262

No files matched your search

+1 -1
View File
@@ -95,7 +95,7 @@
<view class="absolute z-10 top-0 left-0 size-full bg-#33333333" :style="filterStyle"></view>
</view>
<view class="m-4">
<view v-if="userDetail.member.wechatNum" class="m-4">
<view class="my-2 text-size-base">查看微信</view>
<view
v-if="!userWechatInfo.wechatNum"
+139 -107
View File
@@ -9,12 +9,24 @@
<view class="flex w-full flex-col items-center gap-40rpx">
<view class="relative flex w-full items-center">
<input class="h-100rpx w-full rounded-50rpx bg-color-light px-40rpx text-32rpx text-white" type="number"
placeholder="请输入手机号" placeholder-style="color: rgba(255, 255, 255, 0.6)" v-model="phone" maxlength="11" />
<input
class="h-100rpx w-full rounded-50rpx bg-color-light px-40rpx text-32rpx text-white"
type="number"
placeholder="请输入手机号"
placeholder-style="color: rgba(255, 255, 255, 0.6)"
v-model="phone"
maxlength="11"
/>
</view>
<view class="relative flex w-full items-center">
<input class="h-100rpx w-full rounded-50rpx bg-color-light px-40rpx text-32rpx text-white" type="number"
placeholder="验证码" placeholder-style="color: rgba(255, 255, 255, 0.6)" v-model="smsCode" maxlength="4" />
<input
class="h-100rpx w-full rounded-50rpx bg-color-light px-40rpx text-32rpx text-white"
type="number"
placeholder="验证码"
placeholder-style="color: rgba(255, 255, 255, 0.6)"
v-model="smsCode"
maxlength="4"
/>
<view class="absolute right-20rpx text-12px flex-row-center">
<wd-button @click="handleGetCode" :disabled="isTiming" size="medium">
<text>获取验证码</text><text v-if="isTiming"> ({{ countDown }}s)</text>
@@ -22,36 +34,55 @@
</view>
</view>
</view>
<view class="mt-40rpx w-full rounded-full bg-color-theme-dark active:bg-color-theme text-lg text-center py-2"
@click="handleLogin">
<view
class="mt-40rpx w-full rounded-full bg-color-theme-dark active:bg-color-theme text-lg text-center py-2"
@click="handleLogin"
>
登 录 / 注 册
</view>
</view>
<view
class="flex items-center justify-center flex-wrap px-20rpx absolute bottom-40rpx text-center text-14px text-white">
class="flex items-center justify-center flex-wrap px-20rpx absolute bottom-40rpx text-center text-14px text-white"
>
<wd-checkbox v-model="isAgree" />
<text>我已阅读并同意</text>
<text class="text-#D29E52 underline underline-1 underline-solid underline-amber" @click="alert(2, '用户协议')">
<text
class="text-#D29E52 underline underline-1 underline-solid underline-amber"
@click="alert(2, '用户协议')"
>
《用户协议》
</text>
<text>和</text>
<text class="text-#D29E52 underline underline-1 underline-solid underline-amber" @click="alert(3, '隐私政策')">
<text
class="text-#D29E52 underline underline-1 underline-solid underline-amber"
@click="alert(3, '隐私政策')"
>
《隐私政策》
</text>
并同意授权
</view>
<wd-config-provider theme="dark">
<wd-message-box selector="xyBox" />
<wd-message-box selector="xyBox">
<rich-text :nodes="nodes"></rich-text>
</wd-message-box>
<wd-message-box selector="agreeBox">
<view class="flex items-center justify-center flex-wrap px-20rpx text-center text-14px text-white">
<view
class="flex items-center justify-center flex-wrap px-20rpx text-center text-14px text-white"
>
<text>我已阅读并同意</text>
<text class="text-#D29E52 underline underline-1 underline-solid underline-amber" @click="alert(2, '用户协议')">
<text
class="text-#D29E52 underline underline-1 underline-solid underline-amber"
@click="alert(2, '用户协议')"
>
《用户协议》
</text>
<text>和</text>
<text class="text-#D29E52 underline underline-1 underline-solid underline-amber" @click="alert(3, '隐私政策')">
<text
class="text-#D29E52 underline underline-1 underline-solid underline-amber"
@click="alert(3, '隐私政策')"
>
《隐私政策》
</text>
并同意授权
@@ -62,104 +93,105 @@
</template>
<script setup>
import { ref } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app';
import { ref } from 'vue';
import { onShow } from '@dcloudio/uni-app';
import AuthUtil from '@/sheep/api/member/auth';
import { useMessage } from '@/uni_modules/wot-design-uni';
import RecentApi from '@/sheep/api/member/recent';
import AuthUtil from '@/sheep/api/member/auth';
import { useMessage } from '@/uni_modules/wot-design-uni';
import RecentApi from '@/sheep/api/member/recent';
const message = useMessage('xyBox');
const agreeMessage = useMessage('agreeBox');
const message = useMessage('xyBox');
const agreeMessage = useMessage('agreeBox');
const phone = ref('');
const smsCode = ref('');
const isTiming = ref(false);
const countDown = ref(60);
const isAgree = ref(false);
const phone = ref('');
const smsCode = ref('');
const isTiming = ref(false);
const countDown = ref(60);
const isAgree = ref(false);
const nodes = ref(''); // 同意协议的文本
onShow(() => {
if (!phone.value) {
const lastLoginPhone = uni.getStorageSync('last_login_phone')
if (lastLoginPhone) {
phone.value = lastLoginPhone
onShow(() => {
if (!phone.value) {
const lastLoginPhone = uni.getStorageSync('last_login_phone');
if (lastLoginPhone) {
phone.value = lastLoginPhone;
}
}
}
})
const handleGetCode = async () => {
if (!phone.value) return uni.showToast({ title: '请填写手机号', icon: 'none' });
if (
!/^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[1589]))\d{8}$/.test(
phone.value,
)
)
return uni.showToast({ title: '手机号格式错误', icon: 'none' });
const { code } = await AuthUtil.sendSmsCode(phone.value, 1);
if (code !== 0) return;
isTiming.value = true;
timer = setInterval(() => {
countDown.value--;
if (countDown.value === 0) {
isTiming.value = false;
countDown.value = 60;
clearInterval(timer);
}
}, 1000);
};
// 登录
const handleLogin = async () => {
if (!phone.value) return uni.showToast({ title: '请填写手机号', icon: 'none' });
if (
!/^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[1589]))\d{8}$/.test(
phone.value,
)
)
return uni.showToast({ title: '手机号格式错误', icon: 'none' });
if (!smsCode.value) return uni.showToast({ title: '请填写验证码', icon: 'none' });
if (!isAgree.value) {
agreeMessage
.confirm({
title: '授权',
confirmButtonText: '同意并登录',
})
.then(() => {
disposeLogin()
})
return
}
disposeLogin()
};
const disposeLogin = async () => {
if (!phone.value || !smsCode.value) {
return;
}
const { code } = await AuthUtil.smsRegister({ mobile: phone.value, code: smsCode.value });
if (code === 0) {
uni.setStorageSync('last_login_phone', phone.value);
// #ifdef MP-WEIXIN
uni.reLaunch({ url: '/pages/wechat-tabbar/index' });
// #endif
// #ifndef MP-WEIXIN
uni.reLaunch({ url: '/pages/tabbar/home' });
getApp().$vm.init();
// #endif
return;
}
// 清理数据,防止缓存未失效
getApp().$vm.unloadStore();
}
// 2-用户协议;3-隐私协议;
async function alert(type, title) {
const { data } = await RecentApi.getPromotionArticle({ id: type });
message.alert({
msg: data.content.replace(/<\/?[^>]+>/g, ''),
title,
zIndex: 200
});
}
const handleGetCode = async () => {
if (!phone.value) return uni.showToast({ title: '请填写手机号', icon: 'none' });
if (
!/^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[1589]))\d{8}$/.test(
phone.value,
)
)
return uni.showToast({ title: '手机号格式错误', icon: 'none' });
const { code } = await AuthUtil.sendSmsCode(phone.value, 1);
if (code !== 0) return;
isTiming.value = true;
timer = setInterval(() => {
countDown.value--;
if (countDown.value === 0) {
isTiming.value = false;
countDown.value = 60;
clearInterval(timer);
}
}, 1000);
};
// 登录
const handleLogin = async () => {
if (!phone.value) return uni.showToast({ title: '请填写手机号', icon: 'none' });
if (
!/^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[1589]))\d{8}$/.test(
phone.value,
)
)
return uni.showToast({ title: '手机号格式错误', icon: 'none' });
if (!smsCode.value) return uni.showToast({ title: '请填写验证码', icon: 'none' });
if (!isAgree.value) {
agreeMessage
.confirm({
title: '授权',
confirmButtonText: '同意并登录',
})
.then(() => {
disposeLogin();
});
return;
}
disposeLogin();
};
const disposeLogin = async () => {
if (!phone.value || !smsCode.value) {
return;
}
const { code } = await AuthUtil.smsRegister({ mobile: phone.value, code: smsCode.value });
if (code === 0) {
uni.setStorageSync('last_login_phone', phone.value);
// #ifdef MP-WEIXIN
uni.reLaunch({ url: '/pages/wechat-tabbar/index' });
// #endif
// #ifndef MP-WEIXIN
uni.reLaunch({ url: '/pages/tabbar/home' });
getApp().$vm.init();
// #endif
return;
}
// 清理数据,防止缓存未失效
getApp().$vm.unloadStore();
};
// 2-用户协议;3-隐私协议;
async function alert(type, title) {
const { data } = await RecentApi.getPromotionArticle({ id: type });
nodes.value = data.content;
message.alert({
title,
zIndex: 200,
});
}
</script>
+195 -154
View File
@@ -10,7 +10,8 @@
<scroll-view style="height: calc(100dvh - 88px)" scroll-y>
<view
class="mx-4 p-4 rounded-2 bg-gradient-to-b from-#111 to-#222 b-4 b-solid b-t-#D29E52/60 b-l-#D29E52/40 b-r-#D29E52/40 b-b-#D29E52/20">
class="mx-4 p-4 rounded-2 bg-gradient-to-b from-#111 to-#222 b-4 b-solid b-t-#D29E52/60 b-l-#D29E52/40 b-r-#D29E52/40 b-b-#D29E52/20"
>
<view class="text-color-theme-dark font-900 font-italic text-xl mb-1">VIP</view>
<view class="flex-col-center mb-4">
<view class="text-gray mb-2 text-xl font-900 font-italic tracking-1.5">
@@ -24,12 +25,20 @@
<view class="mt-3 px-4">
<scroll-view scroll-x class="w-full" :show-scrollbar="false">
<view class="flex">
<view v-for="item in openTypeList" :key="item.id" class="mr-3 ml-1 my-1" @click="curOpenTypeId = item.id">
<view class="w-220rpx rounded-3 flex-col-center transition-all duration-200" :class="[
curOpenTypeId === item.id
? 'bg-#111 text-white b-3 b-solid b-#D29E52/60'
: 'b-3 b-solid b-#333',
]">
<view
v-for="item in openTypeList"
:key="item.id"
class="mr-3 ml-1 my-1"
@click="curOpenTypeId = item.id"
>
<view
class="w-220rpx rounded-3 flex-col-center transition-all duration-200"
:class="[
curOpenTypeId === item.id
? 'bg-#111 text-white b-3 b-solid b-#D29E52/60'
: 'b-3 b-solid b-#333',
]"
>
<view class="mt-2 text-sm text-#ffffff">{{ item.title }}</view>
<view class="mt-1 text-lg font-900 text-color-theme-dark">
¥{{ fen2yuan(item.preferentialPrice) }}
@@ -50,14 +59,18 @@
<view class="flex justify-between gap-3">
<view
class="flex-1 rounded-full flex-row-center px-4 py-2 b-3 b-solid b-#222 bg-#333 transition-all duration-200"
:style="{ borderColor: payMethod === 'alipay' ? '#D29E52' : '' }" @click="payMethod = 'alipay'">
:style="{ borderColor: payMethod === 'alipay' ? '#D29E52' : '' }"
@click="payMethod = 'alipay'"
>
<image class="size-40rpx mr-2" src="@/static/alipay.png" mode="aspectFill" />
<text>支付宝</text>
</view>
<view
class="flex-1 rounded-full flex-row-center px-4 py-2 b-3 b-solid b-#222 bg-#333 transition-all duration-200"
:style="{ borderColor: payMethod === 'wechat' ? '#D29E52' : '' }" @click="payMethod = 'wechat'">
:style="{ borderColor: payMethod === 'wechat' ? '#D29E52' : '' }"
@click="payMethod = 'wechat'"
>
<image class="size-40rpx mr-2" src="@/static/weixin.png" mode="aspectFill" />
<text>微信支付</text>
</view>
@@ -67,18 +80,26 @@
<!-- 协议 -->
<view class="mt-4 px-4 text-xs text-gray leading-relaxed text-center">
开通即视为同意
<text class="text-color-theme-dark">《荷塘月色会员协议》</text>
<text class="text-color-theme-dark" @click="alert(2, '会员协议')">
《荷塘月色会员协议》
</text>
</view>
<view v-if="openTypeList.length"
<view
v-if="openTypeList.length"
class="mt-4 w-2/3 mx-auto py-2 text-center rounded-full bg-color-theme-dark text-black text-sm active:bg-color-theme"
@click="handleOpenVip">
@click="handleOpenVip"
>
立即开通VIP
</view>
<view class="mt-6 px-4">
<view class="grid grid-cols-3 gap-2">
<view v-for="(item, index) in benefits" :key="index" class="p-2 flex flex-col items-center">
<view
v-for="(item, index) in benefits"
:key="index"
class="p-2 flex flex-col items-center"
>
<view class="mb-1 size-120rpx rounded-full bg-#333 text-center line-height-120rpx">
<uni-icons :type="item.icon" size="32" color="#d29e52"></uni-icons>
</view>
@@ -88,162 +109,182 @@
</view>
</view>
</scroll-view>
<wd-message-box selector="vip-protocol-message-box">
<rich-text :nodes="nodes"></rich-text>
</wd-message-box>
<wd-message-box />
</wd-config-provider>
</template>
<script setup lang="ts">
import { computed, ref, reactive } from 'vue';
// @ts-ignore
import { fen2yuan } from '@/sheep/hooks/useGoods';
import { onLoad, onShow } from '@dcloudio/uni-app';
import RecentApi from '@/sheep/api/member/recent';
import { useMessage } from '@/uni_modules/wot-design-uni';
// @ts-ignore
import $store from '@/sheep/store';
// @ts-ignore
import PayOrderApi from '@/sheep/api/pay/order';
// @ts-ignore
import sheep from '@/sheep';
import { jumpToWechatMiniProgram } from '@/sheep/util/wechat-tool';
import { computed, ref } from 'vue';
// @ts-ignore
import { fen2yuan } from '@/sheep/hooks/useGoods';
import { onLoad, onShow } from '@dcloudio/uni-app';
import RecentApi from '@/sheep/api/member/recent';
import { useMessage } from '@/uni_modules/wot-design-uni';
// @ts-ignore
import $store from '@/sheep/store';
// @ts-ignore
import PayOrderApi from '@/sheep/api/pay/order';
// @ts-ignore
import sheep from '@/sheep';
import { jumpToWechatMiniProgram } from '@/sheep/util/wechat-tool';
const messageBox = useMessage();
const messageBox = useMessage();
const vipProtocolMessageBox = useMessage('vip-protocol-message-box');
interface OpenTypeItem {
id: number;
title: string;
icon: string;
preferentialPrice: number;
originalPrice: number;
duration: number;
status: string;
isHot: boolean;
sort: number;
createTime: number;
}
const benefits: any = [
{ icon: 'chat-filled', desc: '解锁微信', subDesc: '每天10个' },
{ icon: 'chatboxes-filled', desc: '无限畅聊', subDesc: '每天10个' },
{ icon: 'vip-filled', desc: '尊贵身份', subDesc: '专属标识' },
{ icon: 'locked-filled', desc: '个人身份', subDesc: '安全保密' },
{ icon: 'medal-filled', desc: '更多特权', subDesc: '敬请期待' },
];
const payMethodMap = [
{
title: "支付宝",
payment: '',
key: 'alipay'
},
{
title: "微信支付",
payment: 'wx_lite',
key: 'wechat'
interface OpenTypeItem {
id: number;
title: string;
icon: string;
preferentialPrice: number;
originalPrice: number;
duration: number;
status: string;
isHot: boolean;
sort: number;
createTime: number;
}
]
const payMethod = ref<'alipay' | 'wechat'>('alipay'); // 支付方式:alipay / wechat
const openTypeList = ref<OpenTypeItem[]>([]); // 会员类型列表
const curOpenTypeId = ref<number>(); // 当前选择的会员类型id
const currentOpenType = computed<OpenTypeItem | undefined>(() =>
openTypeList.value?.find((item) => item.id === curOpenTypeId.value),
); // 当前选择的会员类型
onLoad(async (params) => {
console.log("onLoad:", params);
if (params) {
if (params.openTypeId && params.payMethod) {
payMethod.value = params.payMethod
disposeWechatPay(params.openTypeId)
}
}
});
const benefits: any = [
{ icon: 'chat-filled', desc: '解锁微信', subDesc: '每天10个' },
{ icon: 'chatboxes-filled', desc: '无限畅聊', subDesc: '每天10个' },
{ icon: 'vip-filled', desc: '尊贵身份', subDesc: '专属标识' },
{ icon: 'locked-filled', desc: '个人身份', subDesc: '安全保密' },
{ icon: 'medal-filled', desc: '更多特权', subDesc: '敬请期待' },
];
const payMethodMap = [
{
title: '支付宝',
payment: '',
key: 'alipay',
},
{
title: '微信支付',
payment: 'wx_lite',
key: 'wechat',
},
];
const nodes = ref(''); // 会员协议文本
const payMethod = ref<'alipay' | 'wechat'>('alipay'); // 支付方式:alipay / wechat
const openTypeList = ref<OpenTypeItem[]>([]); // 会员类型列表
const curOpenTypeId = ref<number>(); // 当前选择的会员类型id
const currentOpenType = computed<OpenTypeItem | undefined>(() =>
openTypeList.value?.find((item) => item.id === curOpenTypeId.value),
); // 当前选择的会员类型
onShow(async () => {
const { data = null } = await RecentApi.getMemberOpenTypeList();
openTypeList.value = data ?? [];
if (openTypeList.value && openTypeList.value[0]) {
curOpenTypeId.value = openTypeList.value[0].id;
}
getChatConfig()
})
// 查询小程序配置
const getChatConfig = async () => {
try {
const { data } = await RecentApi.reportType()
if (data) {
console.log("data:", data);
if (data.vipLookWechtCout) {
benefits[0].subDesc = `每天${data.vipLookWechtCout == -1 ? '无限制' : data.vipLookWechtCout}个`
}
if (data.vipChatUserCout) {
benefits[1].subDesc = `每天${data.vipChatUserCout == -1 ? '无限制' : data.vipChatUserCout}个`
onLoad(async (params) => {
console.log('onLoad:', params);
if (params) {
if (params.openTypeId && params.payMethod) {
payMethod.value = params.payMethod;
disposeWechatPay(params.openTypeId);
}
}
} catch (error) {
console.log("|获取聊天配置|,意外的错误error:", error);
}
}
});
// 开通会员
const handleOpenVip = () => {
if (!curOpenTypeId.value || !currentOpenType.value?.id) {
uni.showToast({ title: '请选择会员类型', icon: 'none' });
return
}
const payMethodItem = payMethodMap.find((item) => item.key === payMethod.value);
if (!payMethodItem) {
uni.showToast({ title: '请选择支付方式', icon: 'none' });
return
}
if (!payMethodItem.payment) {
uni.showToast({ title: `不支持${payMethodItem.title}支付`, icon: 'none' });
return
}
// jumpToWechatPage()
// return
messageBox
.confirm({
msg: '确认开通?',
title: '提示',
})
.then(async () => {
// #ifdef MP-WEIXIN
disposeWechatPay(curOpenTypeId.value)
// #endif
// #ifndef MP-WEIXIN
jumpToWechatPage()
// #endif
})
.catch(() => { });
};
onShow(async () => {
const { data = null } = await RecentApi.getMemberOpenTypeList();
openTypeList.value = data ?? [];
if (openTypeList.value && openTypeList.value[0]) {
curOpenTypeId.value = openTypeList.value[0].id;
}
getChatConfig();
});
// 处理微信支付
const disposeWechatPay = async (openTypeId: any) => {
uni.showLoading({ title: '支付中...', mask: true });
try {
const { code, data } = await RecentApi.memberOpenTypePay({
openTypeId: openTypeId,
// 查看会员协议
async function alert(type: string | number, title: string) {
const { data } = await RecentApi.getPromotionArticle({ id: type });
nodes.value = data?.content || '';
vipProtocolMessageBox.alert({
title,
zIndex: 200,
});
console.log("开通vipId:", data);
if (code !== 0) {
uni.showToast({ title: '创建订单失败', icon: 'none' });
throw new Error('创建订单失败');
}
sheep.$platform.pay(payMethod.value, 'recharge', data);
// 更新用户信息
$store('user').getInfo();
uni.showToast({ title: '支付成功', icon: 'success' });
} catch (error) {
console.error("|处理微信支付|,意外的错误error:", error);
}
}
// 跳转到微信小程序
const jumpToWechatPage = async () => {
await jumpToWechatMiniProgram("openVip", {
openTypeId: curOpenTypeId.value,
payMethod: payMethod.value
})
}
// 查询小程序配置
const getChatConfig = async () => {
try {
const { data } = await RecentApi.reportType();
if (data) {
console.log('data:', data);
if (data.vipLookWechtCout) {
benefits[0].subDesc = `每天${
data.vipLookWechtCout == -1 ? '无限制' : data.vipLookWechtCout
}个`;
}
if (data.vipChatUserCout) {
benefits[1].subDesc = `每天${
data.vipChatUserCout == -1 ? '无限制' : data.vipChatUserCout
}个`;
}
}
} catch (error) {
console.log('|获取聊天配置|,意外的错误error:', error);
}
};
// 开通会员
const handleOpenVip = () => {
if (!curOpenTypeId.value || !currentOpenType.value?.id) {
uni.showToast({ title: '请选择会员类型', icon: 'none' });
return;
}
const payMethodItem = payMethodMap.find((item) => item.key === payMethod.value);
if (!payMethodItem) {
uni.showToast({ title: '请选择支付方式', icon: 'none' });
return;
}
if (!payMethodItem.payment) {
uni.showToast({ title: `不支持${payMethodItem.title}支付`, icon: 'none' });
return;
}
jumpToWechatPage();
return;
messageBox
.confirm({
msg: '确认开通?',
title: '提示',
})
.then(async () => {
// #ifdef MP-WEIXIN
disposeWechatPay(curOpenTypeId.value);
// #endif
// #ifndef MP-WEIXIN
jumpToWechatPage();
// #endif
})
.catch(() => {});
};
// 处理微信支付
const disposeWechatPay = async (openTypeId: any) => {
uni.showLoading({ title: '支付中...', mask: true });
try {
const { code, data } = await RecentApi.memberOpenTypePay({
openTypeId: openTypeId,
});
console.log('开通vipId:', data);
if (code !== 0) {
uni.showToast({ title: '创建订单失败', icon: 'none' });
throw new Error('创建订单失败');
}
sheep.$platform.pay(payMethod.value, 'recharge', data);
// 更新用户信息
$store('user').getInfo();
uni.showToast({ title: '支付成功', icon: 'success' });
} catch (error) {
console.error('|处理微信支付|,意外的错误error:', error);
}
};
// 跳转到微信小程序
const jumpToWechatPage = async () => {
await jumpToWechatMiniProgram('openVip', {
openTypeId: curOpenTypeId.value,
payMethod: payMethod.value,
});
};
</script>
@@ -34,6 +34,7 @@
/>
<wd-status-tip v-else image="content" tip="暂无内容" />
</scroll-list>
<wd-config-provider theme="dark">
<wd-message-box />
<wd-popup