mcwl-pc/app/pages/personal-center/index.vue

463 lines
12 KiB
Vue

<script setup lang="ts">
import { debug } from 'node:console'
import { commonApi } from '@/api/common'
import defaultAvatar from '@/assets/img/default-avatar.png'
import EditUserInfo from '@/components/EditUserInfo.vue'
import { useUserStore } from '@/stores/user'
import { formatDate } from '@/utils/index.ts'
import { debounce } from 'lodash-es'
import { onMounted, onUnmounted, ref } from 'vue'
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: 12,
status: '0',
orderByColumn: 'create_time',
date: null,
endTime: '',
startTime: '',
})
function initPublishParams() {
publishParams.value = {
pageNum: 1,
pageSize: 12,
status: '0',
orderByColumn: 'create_time',
date: null,
endTime: '',
startTime: '',
}
}
// 点赞form的查询条件
const likesParams = ref({
pageNum: 1,
pageSize: 12,
orderByColumn: 'create_time',
})
function initLikesParams() {
likesParams.value = {
pageNum: 1,
pageSize: 12,
orderByColumn: 'create_time',
}
}
const urlList = ref({
mallProduct: {
0: '/model/selectByUserIdModel',
1: '/model/selectByUserIdWorkFlow',
2: '/model/selectByUserIdImage',
},
like: {
0: '/model/likeModel',
1: '/model/likeWorkFlow',
2: '/model/likeImage',
},
})
// 获取数据字典
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()
}
getList()
}
// 切换发布/点赞
function changeTabs(id: string) {
currentState.value = id
currentType.value = '0'
initChangeParams()
}
// 切换模型/工作流/图片
function changeType(id: string) {
currentType.value = id
initChangeParams()
}
function initPageNUm() {
if (currentState.value === 'mallProduct') {
publishParams.value.pageNum = 1
}
else {
likesParams.value.pageNum = 1
}
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://liblibai-web-static.liblib.cloud/liblibai_v4_online/static/_next/static/images/defaultBgImg.381282c0f2b01780c83d8fe6dc0aa90a.png\')',
}
// 定义响应接口
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() {
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) {
dataList.value = res.rows
}
else {
dataList.value = []
}
}
catch (err) {
dataList.value = []
console.log(err)
}
}
getList()
function topedRefresh() {
}
</script>
<template>
<div class="mx-auto container">
<!-- 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
v-if="userInfo.avatar"
class="head-img m-1 h-16 w-16 rounded-full bg-white"
:src="userInfo.avatar ? userInfo.avatar : defaultAvatar"
alt="User Avatar"
>
</client-only>
</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="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>
<!-- User Details -->
<div class="user-info mt-4">
<div v-if="userInfo.nickName" class="nickname text-2xl font-bold">
<!-- {{ userInfo.nickName }} -->微信用户1243
</div>
<div v-if="userInfo.brief" class="info-desc mt-1 text-sm text-gray-700">
{{ userInfo.brief }}
</div>
<div class="production-state mt-4 flex text-sm text-gray-700">
<div class="production-state-item mr-5">
<span class="production-state-number font-bold">{{
selectUserInfo.bean ? selectUserInfo.bean : 0
}}</span>
粉丝
</div>
<div class="production-state-item mr-5">
<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.download ? selectUserInfo.download : 0
}}</span>
作品被使用次数
</div>
<div class="production-state-item">
<span class="production-state-number font-bold">{{
selectUserInfo.likeCount ? selectUserInfo.likeCount : 0
}}</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="结束日期"
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>
<!-- Dialog Components -->
<Authentication ref="authenticationRef" />
<EditUserInfo ref="editUserInfoRef" />
<div class="login-content my-4 grid grid-cols-4 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>
</template>
<style scoped>
.edit-info {
box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.2);
}
</style>