1008 lines
26 KiB
Vue
1008 lines
26 KiB
Vue
<script setup lang="ts">
|
||
import { commonApi } from '@/api/common'
|
||
|
||
import EditUserInfo from '@/components/EditUserInfo.vue'
|
||
import { useUserStore } from '@/stores/user'
|
||
import { formatDate } from '@/utils/index.ts'
|
||
import { Close } from '@vicons/ionicons5'
|
||
import { NConfigProvider, NMessageProvider } from 'naive-ui'
|
||
import { nextTick, onMounted, onUnmounted, ref } from 'vue'
|
||
|
||
import { useRouter } from 'vue-router'
|
||
|
||
const message = useMessage()
|
||
|
||
let pollingTimer: ReturnType<typeof setInterval> | undefined
|
||
|
||
const route = useRoute()
|
||
const { type, status } = route.query as { type: string, status: string }
|
||
|
||
const loading = ref(false)
|
||
const finished = ref(false)
|
||
const total = ref(0) // 总条数
|
||
const loadingTrigger = ref(null)
|
||
|
||
const router = useRouter()
|
||
|
||
const observer = ref<IntersectionObserver | null>(null)
|
||
definePageMeta({
|
||
layout: 'default',
|
||
})
|
||
interface UserInfo {
|
||
nickName?: string // 使用 ? 表示 nickName 是可选的
|
||
avatar?: string
|
||
name?: string
|
||
brief?: string
|
||
}
|
||
const userStore = useUserStore()
|
||
const userInfo: UserInfo = userStore.userInfo
|
||
|
||
// 当前是发布还是点赞?
|
||
const currentState = ref('mallProduct')
|
||
// 当前是模型还是工作流还是图片?
|
||
const currentType = ref('0')
|
||
|
||
const orderOptions = ref([
|
||
{
|
||
dictLabel: '最新',
|
||
dictValue: 'create_time',
|
||
},
|
||
{
|
||
dictLabel: '最热',
|
||
dictValue: 'like_num',
|
||
},
|
||
])
|
||
|
||
const stateList = ref([
|
||
{ id: 'mallProduct', title: '发布' },
|
||
{ id: 'like', title: '点赞' },
|
||
])
|
||
const typeList = ref([
|
||
{ id: '0', title: '模型' },
|
||
{ id: '1', title: '工作流' },
|
||
{ id: '2', title: '图片' },
|
||
])
|
||
|
||
// 发布的form查询条件
|
||
const publishParams = ref({
|
||
pageNum: 1,
|
||
pageSize: 20,
|
||
status: '0',
|
||
orderByColumn: 'create_time',
|
||
date: null,
|
||
endTime: '',
|
||
startTime: '',
|
||
})
|
||
|
||
function initPublishParams() {
|
||
publishParams.value = {
|
||
pageNum: 1,
|
||
pageSize: 20,
|
||
status: '0',
|
||
orderByColumn: 'create_time',
|
||
date: null,
|
||
endTime: '',
|
||
startTime: '',
|
||
}
|
||
}
|
||
|
||
// 点赞form的查询条件
|
||
const likesParams = ref({
|
||
pageNum: 1,
|
||
pageSize: 20,
|
||
orderByColumn: 'create_time',
|
||
})
|
||
|
||
function initLikesParams() {
|
||
likesParams.value = {
|
||
pageNum: 1,
|
||
pageSize: 20,
|
||
orderByColumn: 'create_time',
|
||
}
|
||
}
|
||
|
||
const urlList = ref({
|
||
mallProduct: {
|
||
0: '/personalCenter/selectByUserIdModel',
|
||
1: '/personalCenter/selectByUserIdWorkFlow',
|
||
2: '/personalCenter/selectByUserIdImage',
|
||
},
|
||
like: {
|
||
0: '/personalCenter/likeModel',
|
||
1: '/personalCenter/likeWorkFlow',
|
||
2: '/personalCenter/likeImage',
|
||
},
|
||
})
|
||
|
||
const showInvitationModal = ref(false)
|
||
// 获取数据字典
|
||
|
||
const statusOptions = ref([])
|
||
async function getDictType() {
|
||
try {
|
||
const res = await commonApi.dictType({
|
||
type: 'mall_product_status',
|
||
})
|
||
if (res.code === 200 && res.data.length > 0) {
|
||
statusOptions.value = res.data
|
||
publishParams.value.status = res.data[0].dictValue
|
||
}
|
||
}
|
||
catch (error) {
|
||
console.log(error)
|
||
}
|
||
}
|
||
getDictType()
|
||
|
||
// 编辑用户信息
|
||
interface EditUserInfoType {
|
||
isVisible: boolean
|
||
}
|
||
const editUserInfoRef = ref<EditUserInfoType | null>(null)
|
||
function onEditInfo() {
|
||
if (editUserInfoRef.value) {
|
||
editUserInfoRef.value.isVisible = true
|
||
}
|
||
}
|
||
|
||
// 实名认证
|
||
interface AuthComponentType {
|
||
isVisible: boolean
|
||
}
|
||
const authenticationRef = ref<AuthComponentType | null>(null)
|
||
function onAuth() {
|
||
if (authenticationRef.value) {
|
||
authenticationRef.value.isVisible = true
|
||
}
|
||
}
|
||
|
||
function initChangeParams() {
|
||
if (currentState.value === 'mallProduct') {
|
||
initPublishParams()
|
||
}
|
||
else {
|
||
initLikesParams()
|
||
}
|
||
finished.value = false // 重置加载完成状态
|
||
getList()
|
||
}
|
||
// 切换发布/点赞
|
||
function changeTabs(id: string) {
|
||
currentState.value = id
|
||
currentType.value = '0'
|
||
initChangeParams()
|
||
}
|
||
|
||
// 切换模型/工作流/图片
|
||
function changeType(id: string) {
|
||
if (id === '2') {
|
||
statusOptions.value.forEach((item) => {
|
||
if (item.dictValue === '2') {
|
||
item.disabled = true
|
||
}
|
||
})
|
||
}
|
||
else {
|
||
statusOptions.value.forEach((item) => {
|
||
if (item.dictValue === '2') {
|
||
item.disabled = false
|
||
}
|
||
})
|
||
}
|
||
currentType.value = id
|
||
initChangeParams()
|
||
}
|
||
|
||
function initPageNUm() {
|
||
if (currentState.value === 'mallProduct') {
|
||
publishParams.value.pageNum = 1
|
||
}
|
||
else {
|
||
likesParams.value.pageNum = 1
|
||
}
|
||
finished.value = false // 重置加载完成状态
|
||
getList()
|
||
}
|
||
|
||
// 切换select全部状态/已发布/
|
||
function changeStatus(value: string) {
|
||
publishParams.value.status = value
|
||
initPageNUm()
|
||
}
|
||
|
||
// 切换发布的最热/最新
|
||
function changeOrder(value: string) {
|
||
publishParams.value.orderByColumn = value
|
||
initPageNUm()
|
||
}
|
||
|
||
// 切换点赞的最热/最新
|
||
function changeLikeOrder(value: string) {
|
||
likesParams.value.orderByColumn = value
|
||
initPageNUm()
|
||
}
|
||
|
||
// 切换日期
|
||
async function changeDate(value: string[]) {
|
||
publishParams.value.startTime = `${await formatDate(value[0] as string)} 00:00:00`
|
||
publishParams.value.endTime = `${await formatDate(value[1] as string)} 23:59:59`
|
||
initPageNUm()
|
||
}
|
||
|
||
// 获取用户点赞/粉丝/关注数量
|
||
interface SelectUserInfo {
|
||
likeCount: number
|
||
bean: number
|
||
download: number
|
||
attention: number
|
||
}
|
||
const selectUserInfo = ref<SelectUserInfo>({
|
||
likeCount: 0,
|
||
bean: 0,
|
||
download: 0,
|
||
attention: 0,
|
||
})
|
||
async function getAttention() {
|
||
try {
|
||
const res = await request.get('/attention/selectUserInfo')
|
||
if (res.code === 200) {
|
||
selectUserInfo.value = res.data
|
||
}
|
||
}
|
||
catch (err) {
|
||
console.log(err)
|
||
}
|
||
}
|
||
getAttention()
|
||
|
||
// Banner 样式
|
||
const bannerStyle = {
|
||
backgroundImage:
|
||
'url(\'https://img.zcool.cn/community/special_cover/3a9a64d3628c000c2a1000657eec.jpg\')',
|
||
}
|
||
|
||
// 定义响应接口
|
||
interface ApiResponse<T> {
|
||
code: number
|
||
rows: T[]
|
||
message: string
|
||
}
|
||
// 定义数据接口
|
||
interface UserData {
|
||
id: number
|
||
name: string
|
||
email: string
|
||
status: number
|
||
}
|
||
// 查询发布模型接口
|
||
const dataList = ref([])
|
||
async function getList() {
|
||
if (loading.value || finished.value)
|
||
return
|
||
|
||
loading.value = true
|
||
let params = {}
|
||
if (currentState.value === 'mallProduct') {
|
||
params = publishParams.value
|
||
}
|
||
else {
|
||
params = likesParams.value
|
||
}
|
||
const url = urlList.value[currentState.value][currentType.value]
|
||
try {
|
||
const res = await request.post<ApiResponse<UserData>>(url, params)
|
||
if (res.code === 200) {
|
||
// 如果是第一页,直接赋值,否则追加数据
|
||
if (params.pageNum === 1) {
|
||
dataList.value = res.rows
|
||
}
|
||
else {
|
||
dataList.value = [...dataList.value, ...res.rows]
|
||
}
|
||
|
||
total.value = res.total // 假设接口返回了总条数
|
||
|
||
// 判断是否加载完所有数据
|
||
if (dataList.value.length >= total.value) {
|
||
finished.value = true
|
||
}
|
||
|
||
// 自动增加页码
|
||
if (currentState.value === 'mallProduct') {
|
||
publishParams.value.pageNum++
|
||
}
|
||
else {
|
||
likesParams.value.pageNum++
|
||
}
|
||
}
|
||
}
|
||
catch (err) {
|
||
dataList.value = []
|
||
finished.value = true
|
||
console.log(err)
|
||
}
|
||
finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
onMounted(() => {
|
||
window.addEventListener('scroll', topedRefresh)
|
||
observer.value = new IntersectionObserver(
|
||
([entry]) => {
|
||
if (entry.isIntersecting && !loading.value && !finished.value) {
|
||
getList()
|
||
}
|
||
},
|
||
{
|
||
threshold: 0.1,
|
||
},
|
||
)
|
||
|
||
if (loadingTrigger.value) {
|
||
observer.value.observe(loadingTrigger.value)
|
||
}
|
||
|
||
if (type && type === 'like') {
|
||
currentState.value = type
|
||
}
|
||
if (status === '0' || status === '1' || status === '2') {
|
||
currentType.value = status
|
||
}
|
||
getList()
|
||
})
|
||
|
||
onUnmounted(() => {
|
||
window.removeEventListener('scroll', topedRefresh)
|
||
if (observer.value) {
|
||
observer.value.disconnect()
|
||
}
|
||
})
|
||
|
||
async function topedRefresh() {
|
||
if (import.meta.client) {
|
||
await nextTick()
|
||
window.scrollTo({
|
||
top: 0,
|
||
behavior: 'smooth',
|
||
})
|
||
}
|
||
initPageNUm()
|
||
}
|
||
|
||
function onClearDate() {
|
||
(publishParams.value.startTime = ''), (publishParams.value.endTime = ''), initPageNUm()
|
||
}
|
||
|
||
// 获取粉丝的列表
|
||
const isShowFan = ref(false)
|
||
|
||
const attentionFinished = ref(false)
|
||
const attentionList = ref([])
|
||
const attentionListParams = ref({
|
||
pageNumber: 1,
|
||
pageSize: 20,
|
||
})
|
||
async function getAttentionList() {
|
||
try {
|
||
if (attentionFinished.value)
|
||
return
|
||
const res = await request.post(`/attention/selectToAttention`, {
|
||
...attentionListParams.value,
|
||
})
|
||
if (res.code === 200) {
|
||
if (attentionListParams.value.pageNumber === 1) {
|
||
attentionList.value = res.data.list
|
||
}
|
||
else {
|
||
attentionList.value = [...attentionList.value, ...res.data.list]
|
||
}
|
||
|
||
total.value = res.data.total // 假设接口返回了总条数
|
||
// 判断是否加载完所有数据
|
||
if (attentionList.value.length >= total.value) {
|
||
attentionFinished.value = true
|
||
}
|
||
attentionListParams.value.pageNumber++
|
||
}
|
||
}
|
||
catch (err) {
|
||
attentionList.value = []
|
||
attentionFinished.value = true
|
||
console.log(err)
|
||
}
|
||
}
|
||
getAttentionList()
|
||
|
||
// 获取关注的列表
|
||
const likeFinished = ref(false)
|
||
const likeList = ref([])
|
||
const likeListParams = ref({
|
||
pageNumber: 1,
|
||
pageSize: 20,
|
||
type: null,
|
||
})
|
||
async function getLikeList() {
|
||
try {
|
||
if (likeFinished.value)
|
||
return
|
||
const res = await request.post(`/attention/selectAttentionList`, {
|
||
...likeListParams.value,
|
||
})
|
||
if (res.code === 200) {
|
||
if (likeListParams.value.pageNumber === 1) {
|
||
likeList.value = res.data.list
|
||
}
|
||
else {
|
||
likeList.value = [...likeList.value, ...res.data.list]
|
||
}
|
||
|
||
total.value = res.data.total // 假设接口返回了总条数
|
||
// 判断是否加载完所有数据
|
||
if (likeList.value.length >= total.value) {
|
||
likeFinished.value = true
|
||
}
|
||
likeListParams.value.pageNumber++
|
||
}
|
||
}
|
||
catch (err) {
|
||
likeList.value = []
|
||
likeFinished.value = true
|
||
console.log(err)
|
||
}
|
||
}
|
||
getLikeList()
|
||
|
||
function closefanList() {
|
||
isShowFan.value = false
|
||
}
|
||
|
||
// 去关注/取消关注当前用户
|
||
async function onAttention(item: any) {
|
||
try {
|
||
const userId = userStore.userInfo.userId
|
||
if (userId === item.userId) {
|
||
return message.warning('自己不能关注自己')
|
||
}
|
||
const res = await request.get(`/attention/addAttention?userId=${item.userId}`)
|
||
if (res.code === 200) {
|
||
if (res.data) {
|
||
message.success('关注成功')
|
||
}
|
||
else {
|
||
message.success('取消关注成功')
|
||
}
|
||
item.attention = !item.attention
|
||
}
|
||
}
|
||
catch (err) {
|
||
console.log(err)
|
||
}
|
||
}
|
||
// 过去邀请码
|
||
const invitationCode = ref('')
|
||
async function getInvitation() {
|
||
try {
|
||
const res = await request.get(`/invitation/getInvitationCode`)
|
||
if (res.code === 200) {
|
||
invitationCode.value = res.msg
|
||
}
|
||
}
|
||
catch (err) {
|
||
console.log(err)
|
||
}
|
||
}
|
||
getInvitation()
|
||
|
||
// 获取邀请列表
|
||
// async function getInvitationList() {
|
||
|
||
// }
|
||
|
||
// 复制到粘贴板
|
||
function copyToClipboard(text: string) {
|
||
const textarea = document.createElement('textarea')
|
||
textarea.value = text
|
||
document.body.appendChild(textarea)
|
||
textarea.select()
|
||
const success = document.execCommand('copy')
|
||
document.body.removeChild(textarea)
|
||
|
||
if (success) {
|
||
message.success('复制成功!')
|
||
}
|
||
else {
|
||
message.success('复制成功!')
|
||
}
|
||
}
|
||
|
||
// 复制到粘贴板
|
||
function handlePositiveClick() {
|
||
copyToClipboard(invitationCode.value)
|
||
}
|
||
|
||
const activeTab = ref('like')
|
||
|
||
// 邀请码列表
|
||
const invitationList = ref({})
|
||
async function handleNegativeClick() {
|
||
try {
|
||
const res = await request.get(`/invitation/earningsDisplay`)
|
||
if (res.code === 200) {
|
||
invitationList.value = res.data
|
||
showInvitationModal.value = true
|
||
}
|
||
}
|
||
catch (err) {
|
||
console.log(err)
|
||
}
|
||
}
|
||
function showLike(type: string) {
|
||
isShowFan.value = true
|
||
activeTab.value = type
|
||
}
|
||
function toWallet() {
|
||
router.push({
|
||
path: `/wallet`,
|
||
})
|
||
}
|
||
|
||
// 查询是否已绑定支付宝
|
||
const zfbStatus = ref('0')
|
||
async function getBindStatus() {
|
||
const res = await request.get(`/ali/pay/queryBindStatus`)
|
||
if (res.code === 200) { // '1 绑定 0不绑定
|
||
zfbStatus.value = res.data
|
||
}
|
||
}
|
||
getBindStatus()
|
||
|
||
// 绑定支付宝
|
||
const qrUrl = ref('')
|
||
const isShowBindingModal = ref(false)
|
||
async function showBinding() {
|
||
try {
|
||
const res = await request.get(`/ali/pay/generateQrCode`)
|
||
if (res.code === 200) {
|
||
qrUrl.value = res.data
|
||
isShowBindingModal.value = true
|
||
|
||
pollingTimer && clearTimeout(pollingTimer)
|
||
pollingTimer = setInterval(async () => {
|
||
try {
|
||
const res2 = await request.get(`/ali/pay/queryBindStatus`)
|
||
if (res2.data === '1') {
|
||
await userStore.getUserInfo()
|
||
closeBindingModal()
|
||
message.success('绑定成功!')
|
||
getBindStatus()
|
||
}
|
||
}
|
||
catch (err) {
|
||
closeBindingModal()
|
||
message.warning('绑定失败,请稍后再试!')
|
||
}
|
||
}, 2000)
|
||
}
|
||
}
|
||
catch (err) {
|
||
console.log(err)
|
||
}
|
||
}
|
||
|
||
function closeBindingModal() {
|
||
pollingTimer && clearTimeout(pollingTimer)
|
||
isShowBindingModal.value = false
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<div class="mx-auto relative">
|
||
<!-- Banner Section -->
|
||
<div class="banner-content h-32 bg-blue bg-cover bg-center" :style="bannerStyle" />
|
||
<!-- User Info Section -->
|
||
<div class="info-content mt-[-50px] p-5">
|
||
<div class="edit-info-content flex items-center">
|
||
<!-- Avatar -->
|
||
<div
|
||
class="mc-head mr-5 h-20 w-20 rounded-full bg-white shadow-lg flex items-center justify-center"
|
||
>
|
||
<div class="mc-head-inner h-18 w-18 m-1 rounded-full bg-blue-200">
|
||
<client-only>
|
||
<img
|
||
class="head-img m-1 h-16 w-16 rounded-full bg-white"
|
||
:src="userStore?.userInfo?.avatar"
|
||
alt="User Avatar"
|
||
>
|
||
</client-only>
|
||
<!-- {{ userStore.userInfo.avatar }} -->
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Edit Info Button -->
|
||
<div
|
||
class="edit-info mr-2 cursor-pointer rounded-full bg-white px-5 py-2 shadow-md"
|
||
@click="onEditInfo()"
|
||
>
|
||
编辑资料
|
||
</div>
|
||
<!-- Real Name Verification -->
|
||
<div
|
||
v-if="userStore?.userInfo.name"
|
||
class="edit-info rounded-full bg-white px-5 py-2 shadow-md"
|
||
>
|
||
已经实名
|
||
</div>
|
||
<div
|
||
v-else
|
||
class="edit-info cursor-pointer rounded-full bg-white px-5 py-2 shadow-md"
|
||
@click="onAuth()"
|
||
>
|
||
去实名
|
||
</div>
|
||
<div>
|
||
<n-popconfirm
|
||
class="bg-white ml-2"
|
||
positive-text="复制邀请码"
|
||
negative-text="查看列表"
|
||
:show-icon="false"
|
||
@positive-click="handlePositiveClick"
|
||
@negative-click="handleNegativeClick"
|
||
>
|
||
<template #trigger>
|
||
<n-button class="ml-2 rounded-lg" type="info" round>
|
||
获取邀请码
|
||
</n-button>
|
||
</template>
|
||
邀请码: {{ invitationCode }}
|
||
</n-popconfirm>
|
||
</div>
|
||
<div class="ml-4 cursor-pointer" @click="toWallet()">
|
||
<img src="@/assets/img/wallet.png" alt="">
|
||
</div>
|
||
<div v-if="zfbStatus === '1'" class="bg-[#3875f6] rounded-full px-4 py-2 ml-4 text-white">
|
||
已绑定支付宝
|
||
</div>
|
||
<div v-else class="text-xs px-3 py-2 border border-solid border-[#ccc] rounded-full ml-4 bg-white cursor-pointer" @click="showBinding">
|
||
绑定支付宝
|
||
</div>
|
||
</div>
|
||
|
||
<!-- User Details -->
|
||
<div class="user-info mt-4">
|
||
<div v-if="userStore.userInfo" class="nickname text-xl font-bold">
|
||
{{ userStore.userInfo.nickName }}
|
||
<!-- {{ userInfo.nickName }} -->
|
||
</div>
|
||
<div v-if="userStore.userInfo.brief" class="info-desc mt-1 text-sm text-gray-700">
|
||
{{ userStore.userInfo.brief }}
|
||
</div>
|
||
<div class="production-state mt-4 flex text-sm text-gray-700">
|
||
<div
|
||
class="production-state-item mr-5 cursor-pointer"
|
||
@click="showLike('like')"
|
||
>
|
||
<span class="production-state-number font-bold">{{
|
||
selectUserInfo.bean ? selectUserInfo.bean : 0
|
||
}}</span>
|
||
粉丝
|
||
</div>
|
||
<div
|
||
class="production-state-item mr-5 cursor-pointer"
|
||
@click="showLike('attention')"
|
||
>
|
||
<span class="production-state-number font-bold">{{
|
||
selectUserInfo.attention ? selectUserInfo.attention : 0
|
||
}}</span>
|
||
关注
|
||
</div>
|
||
<div class="production-state-item mr-5">
|
||
<span class="production-state-number font-bold">{{
|
||
selectUserInfo.modelDownloadNum + selectUserInfo.modelRunNum
|
||
}}</span>
|
||
作品被使用次数
|
||
</div>
|
||
<div class="production-state-item">
|
||
<span class="production-state-number font-bold">{{
|
||
selectUserInfo.imageLikeNum + selectUserInfo.modelLikeNum
|
||
}}</span>
|
||
作品被点赞次数
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mc-tabs flex px-5 pb-3" style="border-bottom: 1px solid #e0e0e0">
|
||
<div
|
||
v-for="(item, index) in stateList"
|
||
:key="index"
|
||
class="mc-tabs-btn mr-2 cursor-pointer rounded-full px-5 py-1"
|
||
:class="{
|
||
'bg-black text-white': currentState === item.id,
|
||
'bg-white text-black': currentState !== item.id,
|
||
}"
|
||
@click="changeTabs(item.id)"
|
||
>
|
||
{{ item.title }}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="select-content mt-4 flex items-center justify-between px-5">
|
||
<div class="flex items-center rounded-full bg-gray-100">
|
||
<div
|
||
v-for="(item, index) in typeList"
|
||
:key="index"
|
||
class="m-1 mr-2 cursor-pointer rounded-full px-4 py-1 text-sm"
|
||
:class="{
|
||
'bg-white': item.id === currentType,
|
||
}"
|
||
@click="changeType(item.id)"
|
||
>
|
||
{{ item.title }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Published Works Filters -->
|
||
<div v-if="currentState === 'mallProduct'" class="flex items-center">
|
||
<div>
|
||
<n-select
|
||
v-model:value="publishParams.status"
|
||
:options="statusOptions"
|
||
label-field="dictLabel"
|
||
value-field="dictValue"
|
||
placeholder="请选择"
|
||
style="width: 180px"
|
||
class="mr-2"
|
||
@update:value="changeStatus"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<n-select
|
||
v-model:value="publishParams.orderByColumn"
|
||
:options="orderOptions"
|
||
label-field="dictLabel"
|
||
value-field="dictValue"
|
||
placeholder="请选择"
|
||
class="mr-2 w-28"
|
||
@update:value="changeOrder"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<n-date-picker
|
||
v-model:value="publishParams.date"
|
||
type="daterange"
|
||
style="width: 230px"
|
||
format="yyyy-MM-dd"
|
||
value-format="yyyy.MM.dd"
|
||
range-separator="至"
|
||
start-placeholder="开始日期"
|
||
end-placeholder="结束日期"
|
||
:on-clear="onClearDate"
|
||
clearable
|
||
@update:value="changeDate"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Liked Works Filters -->
|
||
<div v-if="currentState === 'like'" class="flex items-center">
|
||
<NSelect
|
||
v-model:value="likesParams.orderByColumn"
|
||
:options="orderOptions"
|
||
label-field="dictLabel"
|
||
value-field="dictValue"
|
||
placeholder="请选择"
|
||
class="w-32"
|
||
@update:value="changeLikeOrder"
|
||
/>
|
||
</div>
|
||
</div>
|
||
<NConfigProvider>
|
||
<NMessageProvider>
|
||
<Authentication ref="authenticationRef" />
|
||
<EditUserInfo ref="editUserInfoRef" />
|
||
</NMessageProvider>
|
||
</NConfigProvider>
|
||
<!-- Dialog Components -->
|
||
<!-- grid grid-cols-2 lg:grid-cols-4 xl:grid-cols-5 2xl:grid-cols-6 gap-4 p-4 -->
|
||
<div class="login-content my-4 grid xl:grid-cols-4 2xl:grid-cols-5 gap-4 px-5">
|
||
<PersonalCenterCard
|
||
v-for="(item, index) in dataList"
|
||
:key="index"
|
||
:item="item"
|
||
:current-type="currentType"
|
||
:current-state="currentState"
|
||
@toped-refresh="topedRefresh"
|
||
/>
|
||
</div>
|
||
<div ref="loadingTrigger" class="h-10">
|
||
<div v-if="loading" class="text-center text-gray-500">
|
||
加载中...
|
||
</div>
|
||
<div v-if="finished" class="text-center text-gray-500">
|
||
没有更多数据了
|
||
</div>
|
||
</div>
|
||
<div v-if="isShowFan" class="fan-centent">
|
||
<div
|
||
class="w-[550px] h-[calc(100vh-100px)] max-h-[700px] m-auto py-0 px-8 pb-[43px] bg-[#fff] rounded-lg relative"
|
||
>
|
||
<n-icon
|
||
size="20"
|
||
class="mr-2 cursor-pointer absolute top-4 right-2"
|
||
@click="closefanList"
|
||
>
|
||
<Close />
|
||
</n-icon>
|
||
<n-tabs
|
||
v-model:value="activeTab"
|
||
default-value="like"
|
||
justify-content="space-evenly"
|
||
type="line"
|
||
>
|
||
<n-tab-pane name="like" :tab="`粉丝${selectUserInfo.bean || 0}`">
|
||
<n-infinite-scroll
|
||
style="height: calc(100vh - 200px); padding: 0 10px"
|
||
:distance="10"
|
||
@load="getAttentionList"
|
||
>
|
||
<!-- <div class="overflow-y-auto h-[calc(100vh-200px)] px-2"> -->
|
||
<div
|
||
v-for="(item, index) in attentionList"
|
||
:key="index"
|
||
class="flex justify-between items-center p-2"
|
||
>
|
||
<div class="flex items-center">
|
||
<img
|
||
:src="item.avatar || ''"
|
||
alt=""
|
||
class="w-14 h-14 rounded-full mr-2"
|
||
>
|
||
{{ item.nickName }}
|
||
</div>
|
||
<div
|
||
class="bg-[#f4f5f9] px-4 py-2 rounded-full cursor-pointer"
|
||
@click="onAttention(item)"
|
||
>
|
||
{{ item.attention ? "已关注" : "未关注" }}
|
||
</div>
|
||
</div>
|
||
<div
|
||
v-if="attentionList.length === 0"
|
||
class="w-full text-center text-gray-500 font-bold mt-2"
|
||
>
|
||
暂无数据
|
||
</div>
|
||
<!-- </div> -->
|
||
</n-infinite-scroll>
|
||
</n-tab-pane>
|
||
<n-tab-pane name="attention" :tab="`关注${selectUserInfo.attention || 0}`">
|
||
<!-- <div class="overflow-y-auto h-[calc(100vh-200px)] px-2"> -->
|
||
<n-infinite-scroll
|
||
style="height: calc(100vh - 200px); padding: 0 10px"
|
||
:distance="10"
|
||
@load="getLikeList"
|
||
>
|
||
<div
|
||
v-for="(item, index) in likeList"
|
||
:key="index"
|
||
class="flex justify-between items-center p-2"
|
||
>
|
||
<div class="flex items-center">
|
||
<img
|
||
:src="item.avatar || ''"
|
||
alt=""
|
||
class="w-14 h-14 rounded-full mr-2"
|
||
>
|
||
{{ item.nickName }}
|
||
</div>
|
||
<div
|
||
class="bg-[#f4f5f9] px-4 py-2 rounded-full cursor-pointer"
|
||
@click="onAttention(item)"
|
||
>
|
||
{{ item.attention ? "已关注" : "未关注" }}
|
||
</div>
|
||
</div>
|
||
<div
|
||
v-if="attentionList.length === 0"
|
||
class="w-full text-center text-gray-500 font-bold mt-2"
|
||
>
|
||
暂无数据
|
||
</div>
|
||
<!-- </div> -->
|
||
</n-infinite-scroll>
|
||
</n-tab-pane>
|
||
</n-tabs>
|
||
</div>
|
||
</div>
|
||
<n-modal v-model:show="showInvitationModal">
|
||
<n-card
|
||
style="width: 600px"
|
||
:bordered="false"
|
||
size="huge"
|
||
role="dialog"
|
||
aria-modal="true"
|
||
>
|
||
<!-- <template #header-extra>
|
||
噢!
|
||
</template> -->
|
||
<div class="py-4 flex justify-between">
|
||
<div class="text-xl font-bold">
|
||
邀请列表
|
||
</div>
|
||
<div class="text-sm text-gray-600">
|
||
总收益: {{ invitationList.totalAmount }}
|
||
</div>
|
||
</div>
|
||
<div class="rounded-lg">
|
||
<div class="flex w-[100%]">
|
||
<div class="w-[180px] flex items-center py-2">
|
||
头像
|
||
</div>
|
||
<div class="w-[180px] flex items-center py-2">
|
||
邀请人购买数量
|
||
</div>
|
||
<div class="w-[180px] flex items-center py-2">
|
||
邀请人名字
|
||
</div>
|
||
</div>
|
||
<div class="max-h-[500px] overflow-y-auto">
|
||
<div
|
||
v-for="(item, index) in invitationList.earningsDisplayList"
|
||
:key="index"
|
||
class="flex w-[100%] hover:bg-[#f3f3f3] px-2"
|
||
>
|
||
<div class="w-[180px] flex items-center py-2">
|
||
<img class="w-10 h-10 rounded-full" :src="item.user.avatar" alt="">
|
||
</div>
|
||
<div class="w-[180px] flex items-center py-2">
|
||
{{ item.count }}
|
||
</div>
|
||
<div class="w-[180px] flex items-center py-2">
|
||
{{ item.user.userName }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</n-card>
|
||
</n-modal>
|
||
<div v-if="isShowBindingModal" class="fan-centent">
|
||
<div class="relative flex flex-col items-center">
|
||
<div class="bg-[#000] bg-opacity-80 py-10 px-20 flex flex-col items-center justify-center rounded-lg">
|
||
<div class="text-xl text-white mb-4">
|
||
扫码绑定
|
||
</div>
|
||
<n-qr-code :value="qrUrl" :size="150" style="padding: 0;" />
|
||
<div class="text-base text-white mt-4">
|
||
请用手机支付宝扫码
|
||
</div>
|
||
</div>
|
||
<n-icon
|
||
size="30"
|
||
class="cursor-pointer mt-4 text-white"
|
||
@click="closeBindingModal"
|
||
>
|
||
<Close />
|
||
</n-icon>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.fan-centent {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100vw;
|
||
height: 100vh;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
background: rgba(0, 0, 0, 0.4);
|
||
}
|
||
.edit-info {
|
||
box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.2);
|
||
}
|
||
</style>
|