Files
front-pc/pages/personal-detail/index.vue

493 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<KlNavTab active="" :type="1" />
<div class="personal-detail">
<!-- 个人信息头部 -->
<div class="profile-header">
<div class="profile-container">
<div class="avatar-container">
<el-image :src="userForm.avatar" alt="用户头像" class="avatar mt-[4px]" fit="cover" />
</div>
<div class="user-info">
<h2 class="username">{{ userForm.nickname }}</h2>
<!-- <div class="education">手机号码{{ userForm.phone }}</div> -->
<div class="stats">
技能标签<el-tag v-for="label in userForm.labels" :key="label" type="primary" class="mr-[10px]" size="small">{{ label }}</el-tag>
</div>
<div class="description">{{ userForm.description }}</div>
</div>
</div>
</div>
<div class="items-flex-start mx-auto mt-[20px] max-w-[1200px] flex justify-center">
<div class="flex-1">
<!-- 导航标签 -->
<div class="nav-tabs">
<div class="tabs-container">
<div v-for="tab in tabs" :key="tab.id" :class="['tab', { active: query.type === tab.id }]" @click="handleClick(tab.id)">
{{ tab.name }}
</div>
</div>
</div>
<!-- 作品展示区 -->
<div class="content w-[800px]">
<el-table v-loading="result.loading" :data="result.tableList" style="width: 100%" class="mt-[14px]">
<el-table-column prop="date" label="文件信息">
<template #default="scope">
<div class="flex items-center">
<el-image :src="scope.row.iconUrl" fit="cover" alt="" srcset="" class="h-[91px] w-[181px] rd-[4px]" />
<div class="ml-[17px]">
<div class="text-[16px] text-[#333333] font-normal">{{ scope.row.title }}</div>
<div class="text-[14px] text-[#666] font-normal my-[10px]!">{{ dayjs(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</div>
<div class="flex items-center">
<div class="flex items-center">
<img src="~/assets/images/look.png" alt="" srcset="" class="h-[17px]" />
<span class="ml-[4px]">{{ scope.row.previewPoint }}</span>
</div>
<div class="ml-[13px] flex items-center">
<img src="~/assets/images/add.png" alt="" srcset="" class="h-[23px]" />
<span class="ml-[4px]">{{ scope.row.hotPoint }}</span>
</div>
<div class="ml-[13px] flex items-center">
<img src="~/assets/images/chat.png" alt="" srcset="" class="h-[17px]" />
<span class="ml-[4px]">{{ scope.row.commentsPoint }}</span>
</div>
</div>
</div>
</div>
</template>
</el-table-column>
<el-table-column prop="status" label="上传状态" width="180">
<template #default="scope">
{{ handleStatus(scope.row.status) }}
</template>
</el-table-column>
<el-table-column prop="address" label="操作" width="100">
<template #default="scope">
<el-link v-if="scope.row.status === 4" type="primary" :underline="false" @click="handleXiaJia(scope.row)">下架</el-link>
<el-link type="primary" :underline="false" @click="handleDelete(scope.row)">删除</el-link>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div class="mt-[10px] flex justify-center">
<el-pagination
v-model:current-page="query.pageNo"
v-model:page-size="query.pageSize"
:page-sizes="[10, 20, 30]"
:total="result.total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleClickSize"
@current-change="handeClickCurrent"
/>
</div>
</div>
</div>
<!-- 常用软件区域 -->
<div class="software-section">
<h3 class="section-title">最近发表</h3>
<div class="software-list">
<div
v-for="item in mainWork"
:key="item.id"
class="flex cursor-pointer items-center justify-between px-[10px] py-[4px] hover:bg-[#f5f5f5]"
@click="handleClickV2(item.id)"
>
<div class="ellipsis text-[15px] text-[#333333] font-normal">{{ item.title }}发货速度发货速度开发还是看东方航空</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, reactive } from 'vue'
import type { UserExtendSaveReqVO } from '~/api/personal-center/types'
import { getMainWork } from '~/api/drawe-detail/index'
import { getOwnContentPage } from '~/api/personal-center/index'
import { offShelf, deleteResource, getUserExtend } from '~/api/personal-center'
import type { ProjectDrawMemberRespVO } from '~/api/drawe-detail/types'
import dayjs from 'dayjs'
import { useMessage } from '~/utils/useMessage'
const message = useMessage()
// 用户信息
const userForm = reactive<UserExtendSaveReqVO>({
id: undefined,
phone: '',
username: '',
avatar: '',
trueName: '',
city: '',
email: '',
isDomestic: undefined,
area: '',
country: '',
province: '',
county: '',
labels: [],
description: '',
authStatus: 0,
files: [],
nickname: '',
memberId: undefined,
})
const result = reactive({
tableList: [] as any[],
total: 0,
loading: false,
})
const query = reactive({
pageNo: 1,
pageSize: 10,
type: 1,
})
// 标签页
const tabs = ref([
{ id: 1, name: '图纸' },
{ id: 3, name: '模型' },
{ id: 2, name: '文本' },
])
const handleStatus = (status: number) => {
switch (status) {
case 1:
return '草稿'
case 2:
return '提交审核'
case 3:
return '审核成功'
case 4:
return '下架'
default:
return ''
}
}
const handleXiaJia = (row: any) => {
offShelf(row.id).then((res: any) => {
if (res.code === 0) {
ElMessage.success('下架成功')
}
})
}
const handleDelete = async (row: any) => {
const r = await message.confirm('是否删除该资源', '提示')
if (!r) return
deleteResource({ id: row.id }).then((res: any) => {
if (res.code === 0) {
ElMessage.success('删除成功')
}
})
}
const init = async () => {
const res = await getUserExtend()
if (res.code === 0) {
userForm.id = res.data.id
userForm.nickname = res.data.nickname
userForm.phone = res.data.mobile
userForm.email = res.data.email
userForm.isDomestic = +res.data.isDomestic
userForm.country = res.data.country
// await getAdress('province', userForm.isDomestic)
// // @ts-ignore
// userForm.province = +res.data.province
// await getAdress('city', userForm.province)
// // @ts-ignore
// userForm.city = +res.data.city
// await getAdress('county', userForm.city)
// @ts-ignore
userForm.county = +res.data.county
userForm.labels = res.data.labels
userForm.description = res.data.description
userForm.avatar = res.data.avatar
userForm.memberId = res.data.userAuthInfo.memberId
userForm.files = res.data.files.map((item: any) => {
return {
...item,
url: item.url,
name: item.title,
uid: item.id,
status: 'success',
}
})
// 最新发布
handleGetMainWork()
}
}
const fetchData = async () => {
result.loading = true
const res = await getOwnContentPage(query)
if (res.code === 0) {
result.total = res.data.total || 0
result.tableList = res.data.list || []
}
result.loading = false
}
const handleClickSize = (val: number) => {
query.pageSize = val
fetchData()
}
const handleClick = (val: number) => {
query.pageNo = 1
query.type = val
fetchData()
}
const handeClickCurrent = (val: number) => {
query.pageNo = val
fetchData()
}
const handleClickV2 = (id: string | number) => {
navigateTo(`/down-drawe-detail/${id}`) // 修改为在新窗口打开
}
// 获取最新发布
const mainWork = ref<ProjectDrawMemberRespVO[]>([])
const handleGetMainWork = () => {
getMainWork({ id: userForm.id, limit: 10, memberId: userForm.memberId }).then((res) => {
if (res.code === 0) {
mainWork.value = res.data
}
})
}
onMounted(() => {
// 可以在这里获取用户数据
init()
fetchData()
})
</script>
<style scoped lang="scss">
$primary-color: #2563eb;
$background-color: #f7f8fa;
$header-bg: linear-gradient(90deg, #2563eb 0%, #60a5fa 100%);
$max-width: 1200px;
$text-dark: #222;
$text-light: #888;
$card-radius: 12px;
$card-shadow: 0 4px 24px rgba(0, 0, 0, 0.06);
$font-family: 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;
.personal-detail {
width: 100%;
background-color: $background-color;
font-family: $font-family;
.profile-header {
background: #011a52;
color: white;
padding: 40px 0 32px 0;
.profile-container {
max-width: $max-width;
margin: 0 auto;
display: flex;
align-items: flex-start;
padding: 0 32px;
}
}
.avatar-container {
margin-right: 32px;
.avatar {
width: 96px;
height: 96px;
border-radius: 50%;
border: 3px solid rgba(255, 255, 255, 0.7);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
}
.user-info {
flex: 1;
.username {
margin: 0 0 10px 0;
font-size: 24px;
font-weight: 700;
letter-spacing: 1px;
}
.stats {
margin-bottom: 10px;
font-size: 15px;
color: #e0e7ef;
.el-tag {
margin-right: 8px;
border-radius: 8px;
background: #e0e7ef;
color: $primary-color;
border: none;
font-size: 13px;
padding: 2px 12px;
}
}
.description {
font-size: 15px;
line-height: 1.7;
margin-top: 12px;
color: #f3f4f6;
letter-spacing: 0.2px;
}
}
.nav-tabs {
background-color: #fff;
border-radius: $card-radius;
box-shadow: $card-shadow;
margin-bottom: 24px;
.tabs-container {
max-width: $max-width;
margin: 0 auto;
display: flex;
padding: 0 32px;
}
.tab {
padding: 18px 32px 14px 32px;
cursor: pointer;
font-size: 15px;
color: $text-light;
position: relative;
transition: color 0.2s;
&.active {
color: $primary-color;
font-weight: 600;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 3px;
background-color: $primary-color;
border-radius: 2px;
}
}
&:hover {
color: $primary-color;
}
}
}
.content {
background: #fff;
border-radius: $card-radius;
box-shadow: $card-shadow;
padding: 20px 32px 24px 32px;
min-height: 400px;
}
.el-table {
font-size: 15px;
th {
font-weight: 600;
background: #f3f4f6;
color: $text-dark;
letter-spacing: 0.5px;
}
td {
padding: 16px 8px;
color: $text-dark;
}
.el-link {
margin-right: 12px;
font-size: 14px;
letter-spacing: 0.2px;
}
}
.el-pagination {
margin-top: 24px;
}
.software-section {
width: 400px;
margin: 0 0 0 48px;
padding: 0 24px;
.section-title {
font-size: 17px;
font-weight: 700;
margin-bottom: 18px;
color: $primary-color;
letter-spacing: 0.5px;
padding-left: 2px;
}
.software-list {
display: flex;
flex-direction: column;
gap: 10px;
.flex {
border-radius: 4px;
align-items: center;
position: relative;
cursor: pointer;
&::before {
content: '';
position: absolute;
top: 12px;
left: 0;
width: 5px;
height: 5px;
background: #1a65ff;
border-radius: 100%;
}
}
.ellipsis {
font-size: 15px;
color: $text-dark;
font-weight: 500;
letter-spacing: 0.2px;
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.color-999999 {
color: $text-light !important;
font-size: 13px;
font-weight: 400;
margin-left: 16px !important;
letter-spacing: 0.1px;
}
}
}
}
// 响应式优化
@media (max-width: 900px) {
.personal-detail {
.profile-container,
.tabs-container,
.content {
padding-left: 12px;
padding-right: 12px;
}
.software-section {
margin-left: 0;
padding: 0 8px;
}
}
}
@media (max-width: 600px) {
.personal-detail {
.profile-container {
flex-direction: column;
align-items: center;
.avatar-container {
margin-right: 0;
margin-bottom: 12px;
}
}
.content {
padding: 12px 4px;
}
.software-section {
padding: 0 2px;
}
}
}
:deep(.el-input__inner) {
text-align: center !important;
}
</style>