Compare commits
32 Commits
7f7664e68f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| a12afc6bc1 | |||
| ae57f28357 | |||
| 3265c00fba | |||
| ab92461635 | |||
| 3c6ed5a72c | |||
| 9e225417a6 | |||
| 94f1828620 | |||
| 58d3f2e890 | |||
| 5baae7652f | |||
| 3f3ea878b9 | |||
| 89f3b9679d | |||
| b0e5244a79 | |||
| f8176abaad | |||
| 575f6fa2f1 | |||
| 5ee69038fa | |||
| 2bc5a11946 | |||
| b23a85b9ec | |||
| f2c4d14007 | |||
| 82b6f4d63b | |||
| d995ac2b37 | |||
| 01392a6329 | |||
| 689d12e632 | |||
| 8c50ffd479 | |||
| ca7982c974 | |||
| 6c85256b96 | |||
| 972bd2c8b8 | |||
| ecf120221f | |||
| 30fd03590c | |||
| 38fc29ccaa | |||
| 70a75333e8 | |||
| 92ca0a4418 | |||
| 6a002ceb16 |
@ -64,7 +64,7 @@ export const getChannelDetail = (params: { id: string }) => {
|
||||
* @return {Promise}
|
||||
*/
|
||||
export const postscommentpage = (params: { postsId: string; pageNo: number; pageSize: number }) => {
|
||||
return useFetchRequest.get<IResponse<PageResultPostsCommentRespVO>>('/prod-api/app-api/business/posts-comment/page', { query: params })
|
||||
return useDollarFetchRequest.get<IResponse<PageResultPostsCommentRespVO>>('/prod-api/app-api/business/posts-comment/page', { query: params })
|
||||
}
|
||||
/**
|
||||
* 创建帖子评论
|
||||
|
||||
@ -7,22 +7,22 @@ import type { ProjectRespVO, PageResultProjectCommentResVO, ProjectDrawPageRespV
|
||||
* @return {Promise}
|
||||
*/
|
||||
export const getDetail = (params: { id?: number | string }) => {
|
||||
return useFetchRequest.get<IResponse<ProjectRespVO>>('/prod-api/app-api/business/app/project-draw/preview', { query:params })
|
||||
return useFetchRequest.get<IResponse<ProjectRespVO>>('/prod-api/app-api/business/app/project-draw/preview', { query: params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取评论列表
|
||||
* @return {Promise}
|
||||
*/
|
||||
export const getCommentList = (params: { relationId?: number | string; pageNum?: number; pageSize?: number }) => {
|
||||
return useDollarFetchRequest.get<IResponse<PageResultProjectCommentResVO>>('/prod-api/app-api/business/app/project-comment/page', { query:params })
|
||||
export const getCommentList = (params: { relationId?: number | string; pageNum?: number; pageSize?: number; type: number }) => {
|
||||
return useDollarFetchRequest.get<IResponse<PageResultProjectCommentResVO>>('/prod-api/app-api/business/app/project-comment/page', { query: params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 发表评论
|
||||
* @return {Promise}
|
||||
*/
|
||||
export const createComment = (params: { relationId?: number | string; content?: string; projectId?: number | string }) => {
|
||||
export const createComment = (params: { relationId?: number | string; content?: string; projectId?: number | string; type: number }) => {
|
||||
return useDollarFetchRequest.post<IResponse<boolean>>('/prod-api/app-api/business/app/project-comment/create', params)
|
||||
}
|
||||
|
||||
@ -31,14 +31,14 @@ export const createComment = (params: { relationId?: number | string; content?:
|
||||
* @return {Promise}
|
||||
*/
|
||||
export const getRelationRecommend = (params: { type?: number | string; projectType?: number | string }) => {
|
||||
return useFetchRequest.get<IResponse<ProjectDrawPageRespVO[]>>('/prod-api/app-api/business/app/project-draw/top-list', { query:params })
|
||||
return useFetchRequest.get<IResponse<ProjectDrawPageRespVO[]>>('/prod-api/app-api/business/app/project-draw/top-list', { query: params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 举报
|
||||
* @return {Promise}
|
||||
*/
|
||||
export const report = (params: { id?: number | string; title?: string; comments?: string; files?: any; projectId: any; drawId: any }) => {
|
||||
export const report = (params: { id?: number | string; title?: string; comments?: string; files?: any; projectId?: any; drawId: any; type: any }) => {
|
||||
return useDollarFetchRequest.post<IResponse<boolean>>('/prod-api/app-api/business/project-report/create', params)
|
||||
}
|
||||
|
||||
@ -50,6 +50,14 @@ export const getUserInfo = (params: { id?: number | string }) => {
|
||||
return useFetchRequest.get<IResponse<UserExtendSimpleRespDTO>>('/prod-api/app-api/business/app/project-draw/preview-user-info', { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取工具发布人信息
|
||||
*/
|
||||
|
||||
export const getToolUserInfo = (params: { id?: number | string }) => {
|
||||
return useFetchRequest.get<IResponse<UserExtendSimpleRespDTO>>('/prod-api/app-api/business/resource/publish-user-info', { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前用户的主要作品内容
|
||||
*/
|
||||
@ -59,7 +67,7 @@ export const getMainWork = (params: { id?: number | string; limit: number; membe
|
||||
/**
|
||||
* 创建内容信息
|
||||
*/
|
||||
export const createContent = (params: { projectId: any; drawId: any }) => {
|
||||
export const createContent = (params: { projectId?: any; drawId: any; type: any }) => {
|
||||
return useDollarFetchRequest.post<IResponse<boolean>>('/prod-api/app-api/business/project-member-favorites/create', params)
|
||||
}
|
||||
|
||||
|
||||
@ -137,6 +137,7 @@ export interface UserExtendSimpleRespDTO {
|
||||
files: any[]
|
||||
fansCount: number
|
||||
projectCount: number
|
||||
postsNum?: number
|
||||
}
|
||||
|
||||
export interface ProjectDrawMemberRespVO {
|
||||
|
||||
@ -28,13 +28,17 @@ export const loginByMobile = (params: { mobile: string; code: string; socialCode
|
||||
* 发送邮箱验证码
|
||||
*/
|
||||
export const sendEmailCode = (data: { email: string }) => {
|
||||
return useDollarFetchRequest.post<IResponse<any>>('/prod-api/app-api/member/auth/send-email-code?email=' + data.email, {},{
|
||||
return useDollarFetchRequest.post<IResponse<any>>(
|
||||
'/prod-api/app-api/member/auth/send-email-code?email=' + data.email,
|
||||
{},
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
Accept: 'application/json, text/plain, */*',
|
||||
'Access-Control-Allow-Origin-Type': '*',
|
||||
},
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -50,3 +54,10 @@ export const loginByEmail = (params: { email: string; code: string }) => {
|
||||
export const resetPassword = (params: { password: string; code: string }) => {
|
||||
return useDollarFetchRequest.put<IResponse<boolean>>('/prod-api/app-api/member/user/update-password', params)
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权成功通知后台
|
||||
*/
|
||||
export const notifyAuthSuccess = (params: { code: string; state: string }) => {
|
||||
return useDollarFetchRequest.get<IResponse<any>>('/prod-api/app-api/member/auth/wx-login-url', { query: params })
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ export const listWalletRechargePackage = () => {
|
||||
* 获取支付状态
|
||||
*/
|
||||
export const getPayStatus = (params: { id: number }) => {
|
||||
return useDollarFetchRequest.get<IResponse<PayOrderRespVO>>('/prod-api/app-api/pay/order/get', {query:params})
|
||||
return useDollarFetchRequest.get<IResponse<PayOrderRespVO>>('/prod-api/app-api/pay/order/get', { query: params })
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,7 +55,7 @@ export const getTokenByCode = (params: { type: number; code: string; state: stri
|
||||
/**
|
||||
* 社交快捷登录,使用 code 授权码
|
||||
*/
|
||||
export const socialLoginByCode = (params: { type: number; code: string; state: string }) => {
|
||||
export const socialLoginByCode = (params: { type?: number; code?: string; state?: string; openId?: string; sceneStr?: string }) => {
|
||||
return useDollarFetchRequest.post<
|
||||
IResponse<{
|
||||
accessToken: string
|
||||
@ -71,5 +71,5 @@ export const socialLoginByCode = (params: { type: number; code: string; state: s
|
||||
* 获得钱包充值记录分页
|
||||
*/
|
||||
export const getWalletRechargeRecordPage = (params: { pageNo: number; pageSize: number }) => {
|
||||
return useDollarFetchRequest.get<IResponse<PageResultAppPayWalletRechargeRespVO>>('/prod-api/app-api/pay/wallet-transaction/page', {query:params})
|
||||
return useDollarFetchRequest.get<IResponse<PageResultAppPayWalletRechargeRespVO>>('/prod-api/app-api/pay/wallet-transaction/page', { query: params })
|
||||
}
|
||||
|
||||
@ -164,3 +164,35 @@ export const cancelSocialBind = (params: { type: number; openid: string }) => {
|
||||
export const userLogout = () => {
|
||||
return useDollarFetchRequest.del<IResponse<boolean>>('/prod-api/app-api/member/user/unregister-user', {})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取钱包配置
|
||||
*/
|
||||
export const getWalletConfig = () => {
|
||||
return useDollarFetchRequest.get<
|
||||
IResponse<{
|
||||
rechargeRate: number
|
||||
commissionRate: number
|
||||
withdrawRateOfRecharge: number
|
||||
withdrawRateOfEarn: number
|
||||
}>
|
||||
>('/prod-api/app-api/pay/wallet/get-config', {})
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信登录二维码链接
|
||||
*/
|
||||
|
||||
export const getLoginQrcode = () => {
|
||||
return useDollarFetchRequest.get<IResponse<{ sceneStr: string; qrCodeUrl: string }>>('/prod-api/app-api/member/auth/wx-login-url', {})
|
||||
}
|
||||
|
||||
/***
|
||||
* member/auth/checkScanStatus
|
||||
* 检查扫码登录状态
|
||||
*/
|
||||
export const checkScanStatus = (params: { sceneStr: string }) => {
|
||||
return useDollarFetchRequest.get<IResponse<{ status: string; openId: string | null; message: string }>>('/prod-api/app-api/member/auth/checkScanStatus', {
|
||||
query: params,
|
||||
})
|
||||
}
|
||||
|
||||
@ -155,6 +155,7 @@ export interface UserStatisticsCountRespVO {
|
||||
currencyCount: number
|
||||
previewCount: number
|
||||
revenueCount: number
|
||||
revenueBalance: number
|
||||
}
|
||||
|
||||
export interface PageResultProjectMemberFavoritesRespVO {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import * as useDollarFetchRequest from '~/composables/useDollarFetchRequest'
|
||||
import * as useFetchRequest from '~/composables/useFetchRequest'
|
||||
import type { TcreateReq, TpageReq, TpageRes } from './types'
|
||||
import type { TcreateReq, TpageReq, TpageRes, ProjectResourceRespVO } from './types'
|
||||
|
||||
/**
|
||||
* 新建工具箱
|
||||
@ -24,7 +24,7 @@ export const page = (params: any) => {
|
||||
* 获得工具箱
|
||||
*/
|
||||
export const get = (params: { id: string }) => {
|
||||
return useFetchRequest.get<IResponse<TcreateReq>>('/prod-api/app-api/business/resource/get', {
|
||||
return useFetchRequest.get<IResponse<ProjectResourceRespVO>>('/prod-api/app-api/business/resource/get', {
|
||||
query: params,
|
||||
})
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ export interface TcreateReq {
|
||||
projectType: number[]
|
||||
categoryId?: number
|
||||
sourceType?: number
|
||||
categoryName?: string
|
||||
files: {
|
||||
id: number
|
||||
title: string
|
||||
@ -61,3 +62,57 @@ export interface TpageItem {
|
||||
commentsPoint: number
|
||||
ownedUserId: string
|
||||
}
|
||||
|
||||
export interface ProjectResourceRespVO {
|
||||
id: number
|
||||
title: string
|
||||
labels: string[]
|
||||
createAddress: string
|
||||
createIp: string
|
||||
projectType: number[]
|
||||
categoryId: number
|
||||
categoryName: string
|
||||
favoriteId?: number
|
||||
downloadId?: string
|
||||
sourceType: number
|
||||
ownedUserName?: string
|
||||
ownedUserAvatar?: string
|
||||
ownedUserIdInfo: {
|
||||
id: number
|
||||
nickName: string
|
||||
avatar: string
|
||||
}
|
||||
files: {
|
||||
id: number
|
||||
title: string
|
||||
fileId: number
|
||||
drawId: number
|
||||
type: number
|
||||
url: string
|
||||
sort: number
|
||||
size: number
|
||||
}[]
|
||||
coverImages: {
|
||||
id: number
|
||||
title: string
|
||||
fileId: number
|
||||
drawId: number
|
||||
type: number
|
||||
url: string
|
||||
sort: number
|
||||
size: number
|
||||
}[]
|
||||
points: number
|
||||
createTime: string
|
||||
updateTime: string
|
||||
status: number
|
||||
recommend: boolean
|
||||
iconUrl: string
|
||||
hotPoint: number
|
||||
description: string
|
||||
previewPoint: number
|
||||
previewUrl: string
|
||||
previewImageUrl: string
|
||||
commentsPoint: number
|
||||
ownedUserId: string
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
<template>
|
||||
<div class="mt-[30px] w-[100%]">
|
||||
<div class="h-[48px] w-[100%] rounded-[1px] bg-[#F8F8F8] pl-[10px] text-[16px] text-[#333333] font-normal line-height-[50px]"> 共有{{ result.total || 0 }}条评论 </div>
|
||||
<div class="h-[48px] w-[100%] rounded-[1px] bg-[#F8F8F8] pl-[10px] text-[16px] text-[#333333] font-normal line-height-[50px]">
|
||||
共有{{ result.total || 0 }}条评论
|
||||
</div>
|
||||
<div v-for="item in result.list" :key="item.id" class="mt-[20px] border-b-[1px] border-b-[#eee] border-b-solid pb-[14px]">
|
||||
<div class="flex items-start">
|
||||
<el-avatar :src="item.creatorInfo.avatar" alt="" srcset="" class="h-[50px] w-[49px] rounded-full" />
|
||||
@ -44,7 +46,7 @@
|
||||
},
|
||||
projectId: {
|
||||
type: Number,
|
||||
required: true,
|
||||
required: false,
|
||||
},
|
||||
})
|
||||
|
||||
@ -66,7 +68,12 @@
|
||||
|
||||
// 获取评论列表
|
||||
const handleGetCommentList = async () => {
|
||||
const res = await getCommentList({ relationId: props.relationId, pageNum: query.value.pageNo, pageSize: query.value.pageSize })
|
||||
const res = await getCommentList({
|
||||
relationId: props.relationId,
|
||||
pageNum: query.value.pageNo,
|
||||
pageSize: query.value.pageSize,
|
||||
type: props.projectId ? 1 : 2,
|
||||
})
|
||||
if (res.code === 0) {
|
||||
result.value.list = res.data.list
|
||||
result.value.total = res.data.total
|
||||
@ -75,7 +82,7 @@
|
||||
|
||||
// 发表评论
|
||||
const handleCreateComment = async () => {
|
||||
const res = await createComment({ relationId: props.relationId, content: commentContent.value, projectId: props.projectId })
|
||||
const res = await createComment({ relationId: props.relationId, content: commentContent.value, projectId: props.projectId || props.relationId, type: props.projectId ? 1 : 2 })
|
||||
if (res.code === 0) {
|
||||
commentContent.value = ''
|
||||
query.value.pageNo = 1
|
||||
@ -87,8 +94,9 @@
|
||||
() => props.relationId,
|
||||
() => {
|
||||
handleGetCommentList()
|
||||
},{
|
||||
immediate: true
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
<img v-if="props.itemInfo.source === 1" src="~/assets/images/yuan.png" alt="" srcset="" class="mr-[2px] w-[20px] relative bottom-[-4px]" />
|
||||
{{ props.itemInfo.title }}
|
||||
</div>
|
||||
<div class="mt-[8px] text-[15px] text-[#999999] font-normal">by {{ props.itemInfo?.ownedUserIdInfo?.nickName }}</div>
|
||||
<div class="mt-[8px] text-[15px] text-[#666] font-normal">by {{ props.itemInfo?.ownedUserIdInfo?.nickName }}</div>
|
||||
<div class="mt-[4px] text-[13px] text-[#999999] font-normal">{{ dayjs(props.itemInfo.createTime).format('YYYY-MM-DD HH:mm:ss') }}</div>
|
||||
</div>
|
||||
<div><img :src="props.itemInfo?.ownedUserIdInfo?.avatar" alt="" srcset="" class="h-[40px] w-[40px] rd-[50%]" /></div>
|
||||
|
||||
@ -62,12 +62,12 @@
|
||||
|
||||
// 用户中心
|
||||
const handleUserCenter = () => {
|
||||
navigateTo('/personal-Center/info')
|
||||
navigateTo('/personal-center/info')
|
||||
}
|
||||
|
||||
// 消息中心
|
||||
const handleMessageCenter = () => {
|
||||
navigateTo('/personal-Center/message-center')
|
||||
navigateTo('/personal-center/message-center')
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
@ -168,7 +168,7 @@
|
||||
userStore.logout()
|
||||
userStore.$reset()
|
||||
} else if (command === '个人中心') {
|
||||
navigateTo('/personal-Center/info')
|
||||
navigateTo('/personal-center/info')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
<!-- <div class="vip-card-subtitle">中小微企业</div> -->
|
||||
</div>
|
||||
<div class="vip-card-price">
|
||||
<span class="price">¥{{ accDiv(item.payPrice || 0, 100) }}</span>
|
||||
<span class="price">¥{{ item.payPrice }}</span>
|
||||
<span class="per">/1年</span>
|
||||
</div>
|
||||
<ul class="vip-card-features">
|
||||
@ -36,7 +36,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, onMounted } from 'vue'
|
||||
import { listVip, submitPayOrder, getPayStatus } from '~/api/pay/index'
|
||||
import { accDiv } from '~/utils/utils'
|
||||
// import { accDiv } from '~/utils/utils'
|
||||
import { Close } from '@element-plus/icons-vue'
|
||||
import type { AppPayWalletPackageRespVO } from '~/api/pay/types'
|
||||
// @ts-ignore
|
||||
@ -153,8 +153,10 @@
|
||||
.vip-cards {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
justify-content: center;
|
||||
/* justify-content: center; */
|
||||
margin: 24px 0;
|
||||
overflow-x: auto;
|
||||
padding: 10px;
|
||||
}
|
||||
.vip-card {
|
||||
background: #fff;
|
||||
|
||||
77
components/toolbox-components/kl-wallpaper-category.vue
Normal file
77
components/toolbox-components/kl-wallpaper-category.vue
Normal file
@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<div class="box-border w-[100%] border border-[#EEEEEE] rounded-[12px] border-solid bg-[#FFFFFF] px-[20px] py-[26px]">
|
||||
<div class="mb-[10px] flex items-start">
|
||||
<div class="flex-shrink-0 text-[15px] text-[#333333] font-normal">软件分类</div>
|
||||
<div class="ml-[30px] mt-[-6px] flex flex-wrap">
|
||||
<div
|
||||
v-for="(item, index) in projectTypeList"
|
||||
:key="index"
|
||||
class="mb-[8px] mr-[26px] cursor-pointer rounded-[15px] px-[15px] py-[6px] text-[14px] text-[#666666] font-normal"
|
||||
:class="item.id === query ? '!bg-[#ebeefe] !text-[#1A65FF]' : ''"
|
||||
@click="handleClick(item)"
|
||||
>{{ item.name }}</div
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { parent } from '~/api/upnew/index'
|
||||
import type { pageReq } from '~/api/upnew/types'
|
||||
import { getDictTree } from '~/api/home/index'
|
||||
import { ArrowRight } from '@element-plus/icons-vue'
|
||||
|
||||
const props = defineProps({
|
||||
type: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
groundId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
})
|
||||
|
||||
const query = defineModel<string | undefined>('modelValue', {
|
||||
required: true,
|
||||
})
|
||||
|
||||
// 服务端渲染兼容方案:顺序执行异步操作
|
||||
// 1. 先获取面包屑数据(已在上面通过useAsyncData获取)
|
||||
|
||||
// 2. 顺序获取分类下拉框数据
|
||||
// 创建一个函数来获取分类数据,确保服务端渲染时能获取到数据
|
||||
const getProjectTypeList = async () => {
|
||||
try {
|
||||
// 获取分类数据
|
||||
const res = await parent({
|
||||
type: 3,
|
||||
parentId: 0,
|
||||
})
|
||||
const all = [{ id: '-1', name: '全部' }]
|
||||
return [...all, ...res.data]
|
||||
} catch (error) {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
// 使用useAsyncData获取分类列表,确保服务端渲染兼容性
|
||||
const { data: projectTypeList } = await useAsyncData(
|
||||
`projectType-draw-toolbox-${props.type}-${query.value}}`,
|
||||
getProjectTypeList,
|
||||
{ server: true } // 确保在服务端执行
|
||||
)
|
||||
|
||||
const handleClick = (row: any) => {
|
||||
query.value = row.id
|
||||
}
|
||||
|
||||
const handleClickBread = (row: any, index: number) => {
|
||||
query.value = row.id
|
||||
}
|
||||
</script>
|
||||
62
components/withdraw/index.vue
Normal file
62
components/withdraw/index.vue
Normal file
@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<el-dialog v-model="dialogVisible" title="提现申请" width="600" :before-close="handleClose">
|
||||
<el-form :model="form" label-width="80px">
|
||||
<el-form-item label="收款账户" prop="amount">
|
||||
<el-input v-model="form.amount" placeholder="微信手机账号" />
|
||||
<div class="text-12px color-#A8ABB2">*仅支持微信收款,用户需在微信[收付款>向手机号转账>手机号收款设置]开启收款开关*</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="提现类型" prop="amount">
|
||||
<el-radio-group v-model="form.amount">
|
||||
<el-radio :label="1">收益提现</el-radio>
|
||||
<el-radio :label="2">全部提现</el-radio>
|
||||
</el-radio-group>
|
||||
<div class="text-12px color-#A8ABB2">*收益提现将收益金币提现,全部提现可将充值金币提现*</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="提现金额" prop="amount">
|
||||
<div class="flex items-center">
|
||||
<el-input-number v-model="form.amount" :controls="false" :min="0" placeholder="请输入提现金额" class="w-150px!" />
|
||||
<div class="ml-10px">[可提现金币数<span class="text-red">1200</span>=<span class="text-red">120</span> 元]</div>
|
||||
</div>
|
||||
<div class="text-12px color-#A8ABB2">*提现金币比例10金币=1元最低提现额度100元*</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="text-12px color-red">
|
||||
提示:收益金币提现正常收取平台手续费{{ walletConfig?.withdrawRateOfEarn }}%,如需将充值金币提现,选择“全部提现”选项,因涉及充值赠送金额,将收取{{ walletConfig?.withdrawRateOfRecharge }}%高额手续费,如果恶意套利提现,将提现审核不通过!
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="dialogVisible = false"> 立即申请 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getWalletConfig } from '~/api/personal-center/index'
|
||||
const dialogVisible = defineModel('modelValue', {
|
||||
default: false,
|
||||
})
|
||||
|
||||
const form = reactive({
|
||||
amount: 0,
|
||||
})
|
||||
|
||||
const handleClose = (done: () => void) => {
|
||||
done()
|
||||
}
|
||||
const walletConfig = ref<{
|
||||
rechargeRate: number
|
||||
commissionRate: number
|
||||
withdrawRateOfRecharge: number
|
||||
withdrawRateOfEarn: number
|
||||
}>()
|
||||
|
||||
onMounted(() => {
|
||||
getWalletConfig().then((res) => {
|
||||
walletConfig.value = res.data
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
99
components/wx.vue
Normal file
99
components/wx.vue
Normal file
@ -0,0 +1,99 @@
|
||||
<!-- 二维码弹窗 -->
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog title="微信登录" v-model="visible" width="30%" :close-on-click-modal="false" :close-on-press-escape="false" @before-close="close">
|
||||
<qrcode-vue :value="qrcode" :size="300" :margin="2" colorDark="#2c3e50" colorLight="#f8f9fa" errorCorrectionLevel="H" />
|
||||
<!-- 扫码状态 -->
|
||||
<div class="text-center">
|
||||
<span>{{ checkLoginStatus }}</span>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import useUserStore from '~/stores/user'
|
||||
import { getLoginQrcode, checkScanStatus } from '~/api/personal-center/index'
|
||||
import QrcodeVue from 'qrcode.vue'
|
||||
const store = useUserStore()
|
||||
|
||||
const visible = defineModel('visible', {
|
||||
default: false,
|
||||
})
|
||||
|
||||
const checkLoginStatus = computed(() => {
|
||||
const type = {
|
||||
EXPIRED: '已过期',
|
||||
CONFIRMED: '已确认',
|
||||
SCANNED: '已扫码',
|
||||
WAITING: '等待扫码',
|
||||
SUCCESS: '登录成功',
|
||||
}
|
||||
if (checkLoginInfo.value) {
|
||||
return type[checkLoginInfo.value.status as keyof typeof type]
|
||||
}
|
||||
return '微信扫码登录'
|
||||
})
|
||||
|
||||
const qrcode = ref('')
|
||||
const sceneStr = ref('')
|
||||
const timer = ref<any>()
|
||||
const getQrcode = async () => {
|
||||
// 获取二维码
|
||||
const res = await getLoginQrcode()
|
||||
if (res.code === 0) {
|
||||
const jsonurl = res.data.qrCodeUrl
|
||||
const qrCodeUrl = jsonurl ? JSON.parse(jsonurl) : ''
|
||||
|
||||
if (qrCodeUrl?.qrCodeUrl) {
|
||||
qrcode.value = qrCodeUrl.qrCodeUrl
|
||||
sceneStr.value = res.data.sceneStr
|
||||
|
||||
// 轮询检查扫码状态
|
||||
getCheckScanStatus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const checkLoginInfo = ref<{ status: string; openId: string | null; message: string }>()
|
||||
const getCheckScanStatus = async () => {
|
||||
// 轮询检查扫码状态
|
||||
timer.value = setInterval(async () => {
|
||||
const response = await checkScanStatus({ sceneStr: sceneStr.value })
|
||||
if (response.code === 0) {
|
||||
checkLoginInfo.value = response.data
|
||||
if (checkLoginInfo.value.status === 'SCANNED') {
|
||||
// 登录
|
||||
await store.getTokenV2({ openId: checkLoginInfo.value.openId as string, sceneStr: sceneStr.value })
|
||||
// 扫码成功
|
||||
visible.value = false
|
||||
clearInterval(timer.value)
|
||||
} else if (checkLoginInfo.value.status === 'EXPIRED') {
|
||||
// 二维码过期
|
||||
clearInterval(timer.value)
|
||||
// 重新获取二维码
|
||||
getQrcode()
|
||||
}
|
||||
}
|
||||
}, 5000)
|
||||
}
|
||||
|
||||
const close = () => {
|
||||
visible.value = false
|
||||
qrcode.value = ''
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 获取二维码
|
||||
getQrcode()
|
||||
})
|
||||
// 关闭定时器
|
||||
onUnmounted(() => {
|
||||
clearInterval(timer.value)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-dialog__body) {
|
||||
text-align: center !important;
|
||||
}
|
||||
</style>
|
||||
@ -1,18 +1,20 @@
|
||||
import { useFetch } from '#app'
|
||||
import type { UseFetchOptions } from '#app'
|
||||
import { isArray } from '~/utils/utils'
|
||||
import useUserStore from '~/stores/user'
|
||||
|
||||
const useServerRequest = async <T>(url: string, opts?: UseFetchOptions<T, unknown>) => {
|
||||
const token = useToken()
|
||||
const runtimeConfig = useRuntimeConfig()
|
||||
const userStore = useUserStore()
|
||||
|
||||
const defaultOptions: UseFetchOptions<unknown> = {
|
||||
baseURL: runtimeConfig.public.apiBase,
|
||||
onRequest({ options }) {
|
||||
options.headers = options.headers || {}
|
||||
|
||||
if (token.value) {
|
||||
options.headers.set('Authorization', `Bearer ${token.value}`)
|
||||
if (token.value || userStore.token) {
|
||||
options.headers.set('Authorization', `Bearer ${token.value || userStore.token}`)
|
||||
}
|
||||
},
|
||||
onResponse({ response }) {
|
||||
|
||||
20
layouts/success.vue
Normal file
20
layouts/success.vue
Normal file
@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<div class="layout-wrap">
|
||||
<div class="flex flex-1 flex-col">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup></script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.layout-wrap {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #fbfcff;
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
}
|
||||
</style>
|
||||
139
pages/auth-success/index.vue
Normal file
139
pages/auth-success/index.vue
Normal file
@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<div class="auth-success-container">
|
||||
<!-- 顶部成功图标 -->
|
||||
<div class="success-icon">
|
||||
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="40" cy="40" r="40" fill="#4CD964" />
|
||||
<path d="M25 40L35 50L55 30" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<!-- 标题和描述 -->
|
||||
<div class="text-content">
|
||||
<h1 class="title">授权成功</h1>
|
||||
<p class="desc">
|
||||
您已完成微信授权,<br />
|
||||
请返回电脑端继续操作
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 倒计时提示 -->
|
||||
<!-- <div class="countdown" v-if="countdown > 0">
|
||||
<p>页面将在 {{ countdown }} 秒后自动关闭</p>
|
||||
</div> -->
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<!-- <div class="btn-group">
|
||||
<button class="close-btn" @click="closePage">立即关闭</button>
|
||||
</div> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { notifyAuthSuccess } from '~/api/login/index'
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
const route = useRoute()
|
||||
definePageMeta({
|
||||
layout: 'success',
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
notifyAuthSuccess({ code: route.query.code as string, state: route.query.state as string }).then(() => {
|
||||
console.log('Notified backend of auth success')
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.auth-success-container {
|
||||
min-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
background-color: #f5f7fa;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.success-icon {
|
||||
margin-bottom: 30px;
|
||||
animation: pop 0.5s ease-out;
|
||||
}
|
||||
|
||||
@keyframes pop {
|
||||
0% {
|
||||
transform: scale(0.8);
|
||||
opacity: 0;
|
||||
}
|
||||
70% {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.text-content {
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin: 0 0 15px 0;
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 16px;
|
||||
color: #666;
|
||||
line-height: 1.6;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.countdown {
|
||||
margin-bottom: 50px;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
background-color: #07c160;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 24px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
|
||||
.close-btn:hover {
|
||||
background-color: #06b355;
|
||||
}
|
||||
|
||||
/* 适配小屏手机 */
|
||||
@media (max-width: 320px) {
|
||||
.title {
|
||||
font-size: 22px;
|
||||
}
|
||||
.desc {
|
||||
font-size: 15px;
|
||||
}
|
||||
.close-btn {
|
||||
height: 44px;
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -13,15 +13,15 @@
|
||||
</div>
|
||||
<div class="mt-[19px] flex items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
<img src="~/assets/images/look.png" alt="" srcset="" class="mr-[4px] h-[17px]" />
|
||||
<img src="~/assets/images/look.png" alt="" srcset="" class="mr-[4px] h-[14px]" />
|
||||
<span class="text-[#666666]">{{ channelDetail?.likeNum || 0 }}人赞过</span>
|
||||
<div class="ml-[16px] flex items-center">
|
||||
<img src="~/assets/images/add.png" alt="" class="mr-[4px] h-[23px]" />
|
||||
<img src="~/assets/images/add.png" alt="" class="mr-[4px] h-[20px]" />
|
||||
<span class="text-[#666666]">{{ channelDetail?.commentNum || 0 }}评论</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-[16px] flex items-center">
|
||||
<img src="~/assets/images/chat.png" alt="" srcset="" class="mr-[4px] h-[17px]" />
|
||||
<img src="~/assets/images/chat.png" alt="" srcset="" class="mr-[4px] h-[14px]" />
|
||||
<span class="text-[#666666]">{{ channelDetail?.browseNum || 0 }}人看过</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -104,7 +104,6 @@
|
||||
const channelId = computed(() => route.params.channelId as string)
|
||||
const pageNo = computed(() => Number(route.params.pageNo))
|
||||
|
||||
console.log(channelId.value, pageNo.value)
|
||||
|
||||
// const channelDetail = ref<TGetChannelPostsRes>()
|
||||
// const commentList = reactive<PageResultPostsCommentRespVO>({
|
||||
|
||||
@ -11,14 +11,14 @@
|
||||
<div
|
||||
class="box-border h-[60px] w-[1019px] flex items-center justify-between border border-[#EEEEEE] rounded-[12px] border-solid bg-[#FFFFFF] px-[27px] py-[24px]"
|
||||
>
|
||||
<div class="text-[20px] text-[#333333] font-normal"> {{ detail?.title }}</div>
|
||||
<div class="text-[16px] text-[#333333] font-normal"> {{ detail?.title }}</div>
|
||||
<div class="flex items-center">
|
||||
<img :src="detail?.ownedUserIdInfo?.avatar" alt="" srcset="" class="h-[30px] w-[30px] rd-[50%]" />
|
||||
<span class="ml-[12px] color-[#999999]">by {{ detail?.ownedUserIdInfo?.nickName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ml-[23px] flex flex-1 text-[18px] text-[#FFFFFF] font-normal">
|
||||
<div class="ml-[23px] flex flex-1 text-[16px] text-[#FFFFFF] font-normal">
|
||||
<div class="h-[60px] w-[160px] flex cursor-pointer items-center justify-center rounded-[8px] bg-[#1A65FF]" @click="handleDownload">
|
||||
<img src="~/assets/images/download.png" alt="" srcset="" class="mr-[4px] h-[22px] w-[27px]" />
|
||||
{{ detail?.points === 0 ? '免费下载' : '立即下载' }}
|
||||
@ -45,16 +45,16 @@
|
||||
<div>
|
||||
<ThumBnail :data="detail?.coverImages" :type="detail?.type"></ThumBnail>
|
||||
</div>
|
||||
<div class="mb-[20px] mt-[34px] flex items-center text-[16px] text-[#333333] font-normal">
|
||||
<div class="h-[24px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div><span class="ml-[10px]">{{ detail?.title }}描述</span></div
|
||||
<div class="mb-[20px] mt-[34px] flex items-center text-[14px] text-[#333333] font-normal">
|
||||
<div class="h-[20px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div><span class="ml-[10px]">{{ detail?.title }}描述</span></div
|
||||
>
|
||||
<div
|
||||
class="box-border min-h-[90px] w-[1019px] border border-[#EEEEEE] rounded-[6px] border-solid bg-[#FFFFFF] pa-[24px] text-[14px] text-[#333333] font-normal"
|
||||
>
|
||||
{{ detail?.description }}
|
||||
</div>
|
||||
<div id="section1" class="mb-[20px] mt-[34px] flex items-center text-[16px] text-[#333333] font-normal">
|
||||
<div class="h-[24px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div><span class="ml-[10px]">{{ detail?.title }}附件</span></div
|
||||
<div id="section1" class="mb-[20px] mt-[34px] flex items-center text-[14px] text-[#333333] font-normal">
|
||||
<div class="h-[20px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div><span class="ml-[10px]">{{ detail?.title }}附件</span></div
|
||||
>
|
||||
<div class="box-border w-[1019px] border border-[#EEEEEE] rounded-[6px] border-solid bg-[#FFFFFF] pa-[24px]">
|
||||
<div class="border-b-[1px] border-b-[#eee] border-b-solid p-b-[10px]">
|
||||
@ -86,8 +86,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 关联项目 -->
|
||||
<div class="mb-[20px] mt-[34px] flex items-center text-[16px] text-[#333333] font-normal">
|
||||
<div class="h-[24px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div
|
||||
<div class="mb-[20px] mt-[34px] flex items-center text-[14px] text-[#333333] font-normal">
|
||||
<div class="h-[20px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div
|
||||
><span class="ml-[10px]">关联{{ detail?.type === 1 ? '图纸' : detail?.type === 2 ? '文本' : '模型' }}</span></div
|
||||
>
|
||||
<el-row :gutter="20">
|
||||
@ -97,8 +97,8 @@
|
||||
</el-row>
|
||||
<el-empty v-if="!detail?.relationDraws?.length" description="暂无数据"></el-empty>
|
||||
<!-- 关联模型 -->
|
||||
<div class="mb-[20px] mt-[34px] flex items-center text-[16px] text-[#333333] font-normal">
|
||||
<div class="h-[24px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div
|
||||
<div class="mb-[20px] mt-[34px] flex items-center text-[14px] text-[#333333] font-normal">
|
||||
<div class="h-[20px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div
|
||||
><span class="ml-[10px]">相关{{ detail?.type === 1 ? '图纸' : detail?.type === 2 ? '文本' : '模型' }}推荐</span></div
|
||||
>
|
||||
<el-row :gutter="20">
|
||||
@ -146,7 +146,7 @@
|
||||
<div class="h-[20px]">
|
||||
<img src="~/assets/images/user4.png" alt="fans" class="w-[80%] rounded-full vertical-top" />
|
||||
</div>
|
||||
<div class="relative top-[-3px] ml-[8px] text-[14px] text-[#666] font-normal">粉丝: {{ userInfo.fansCount || 0 }}</div>
|
||||
<div class="relative top-[-3px] ml-[8px] text-[14px] text-[#666] font-normal">发帖数: {{ userInfo.postsNum || 0 }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -163,8 +163,8 @@
|
||||
|
||||
<div class="mt-[20px] h-[1px] w-[336px] rounded-[1px] bg-[#EEEEEE]"></div>
|
||||
<div class="mt-[20px] flex items-center">
|
||||
<div class="h-[24px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div>
|
||||
<span class="ml-[10px] text-[16px]">最新发布</span>
|
||||
<div class="h-[20px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div>
|
||||
<span class="ml-[10px] text-[14px]">最新发布</span>
|
||||
</div>
|
||||
<div class="mt-[10px]">
|
||||
<div
|
||||
@ -361,6 +361,7 @@
|
||||
comments: value,
|
||||
projectId: detail.value?.projectId,
|
||||
drawId: detail.value?.id,
|
||||
type: detail.value?.type,
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
ElMessage.success('举报成功')
|
||||
@ -380,6 +381,7 @@
|
||||
: await createContent({
|
||||
projectId: detail.value?.projectId,
|
||||
drawId: detail.value?.id,
|
||||
type: detail.value?.type,
|
||||
})
|
||||
if (res.code === 0) {
|
||||
ElMessage.success(`${detail.value?.favoriteId ? '取消' : '收藏'}成功`)
|
||||
|
||||
@ -10,8 +10,8 @@
|
||||
<div class="swiper-button-prev"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-[20px] mt-[34px] flex items-center text-[16px] text-[#333333] font-normal">
|
||||
<div class="h-[24px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div>
|
||||
<div class="mb-[20px] mt-[34px] flex items-center text-[14px] text-[#333333] font-normal">
|
||||
<div class="h-[20px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div>
|
||||
<span class="ml-[10px]">{{ props.type === 1 ? '图纸' : props.type === 2 ? '文本' : '模型' }}</span>
|
||||
</div>
|
||||
<div class="box-border h-[126px] w-[1019px] border border-[#EEEEEE] rounded-[6px] border-solid bg-[#FFFFFF] pa-[23px]">
|
||||
|
||||
@ -79,7 +79,7 @@
|
||||
<div class="text-[15px] color-[#999]">{{ dayjs(item.createTime).format('MM-DD') }}</div>
|
||||
</div>
|
||||
<!-- 暂无数据 -->
|
||||
<el-empty v-if="!newDrawList.length" description="暂无数据"></el-empty>
|
||||
<el-empty v-if="!newDrawList?.length" description="暂无数据"></el-empty>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -64,7 +64,7 @@
|
||||
</div>
|
||||
<div v-if="!isLogin" class="mt-[30px] flex justify-between px-[20px]">
|
||||
<img src="~/assets/images/qq-v2.png" alt="QQ登录" class="social-icon" @click="handleLoginQQ" />
|
||||
<img src="~/assets/images/weixin-v2.png" alt="微信登录" class="social-icon" @click="handleLoginWechat" />
|
||||
<img src="~/assets/images/weixin-v2.png" alt="微信登录" class="social-icon" @click="handleLoginWechatV2" />
|
||||
<img src="~/assets/images/email-v2.png" alt="邮箱登录" class="social-icon" @click="handleLoginEmail" />
|
||||
<img src="~/assets/images/phone-v2.png" alt="手机登录" class="social-icon" @click="handleLoginPhone" />
|
||||
</div>
|
||||
@ -73,6 +73,9 @@
|
||||
<img src="~/assets/images/sign.png" alt="签到奖励" class="bonus-image" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- wx二维码弹窗 -->
|
||||
<wx v-model:visible="visible" v-if="visible" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -90,6 +93,12 @@
|
||||
return !!userStore.token
|
||||
})
|
||||
|
||||
// 打开微信二维码
|
||||
const visible = ref<boolean>(false)
|
||||
const handleLoginWechatV2 = () => {
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
// 获取用户统计信息
|
||||
const userStaticInfo = ref<UserStatisticsCountRespVO>()
|
||||
const fetchUserStatistics = async () => {
|
||||
|
||||
@ -44,7 +44,6 @@
|
||||
}
|
||||
|
||||
const { data: noticeList } = await getNoticeList()
|
||||
console.log(noticeList)
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@ -155,7 +155,7 @@
|
||||
const all = [{ id: '0', name: '全部分类', children: [] }]
|
||||
if (Array.isArray(res.data) && res.data?.length > 0) {
|
||||
const total = [...res.data, ...all]
|
||||
// query.projectTypeDay = total[0]?.id || ''
|
||||
query.projectTypeDay = total[0]?.id || ''
|
||||
// query.projectType = total[0]!.children?.[0]?.id || ''
|
||||
return total
|
||||
}
|
||||
@ -206,10 +206,10 @@
|
||||
// }
|
||||
|
||||
const handleHover = (item: ProjectDictNodeVO) => {
|
||||
query.projectTypeDay = item.id || ''
|
||||
if (item.name === '全部分类') return
|
||||
query.projectTypeDay = item.id || ''
|
||||
// projectTypeListChildren.value = item.children || []
|
||||
query.projectType = item.children?.[0].id || ''
|
||||
// query.projectType = item.id || ''
|
||||
// 热门数据
|
||||
getHotTop()
|
||||
}
|
||||
|
||||
@ -44,8 +44,6 @@
|
||||
const sideMenu = ref()
|
||||
const menuItemRefs = ref<HTMLElement[]>([])
|
||||
|
||||
// const menuItems = ref<ProjectDictNodeVO[]>([]);
|
||||
|
||||
// 等待数据加载完成再进行渲染 :courseData 对data进行别名赋值
|
||||
const {
|
||||
data: menuItems,
|
||||
@ -64,9 +62,6 @@
|
||||
})
|
||||
|
||||
const showSubMenu = (index: number) => {
|
||||
// if (menuItems.value.length === index + 1) {
|
||||
// return
|
||||
// }
|
||||
activeIndex.value = index
|
||||
const dom = menuItemRefs.value[index].getBoundingClientRect()
|
||||
console.log(dom)
|
||||
@ -78,21 +73,6 @@
|
||||
}
|
||||
|
||||
const handleSubmenuClick = (primary: ProjectDictNodeVO) => {
|
||||
// const normal = { id: "0", name: "图纸库", isChildren: false };
|
||||
// const level = [primary, secondary, tertiary]
|
||||
// .filter(Boolean)
|
||||
// .map((item) => ({
|
||||
// id: item?.id,
|
||||
// name: item?.name,
|
||||
// isChildren: item?.children?.length ? false : true,
|
||||
// }));
|
||||
// if (primary?.id === "0") {
|
||||
// level[0].name = "图纸库";
|
||||
// } else {
|
||||
// level.unshift(normal);
|
||||
// }
|
||||
|
||||
// navigateTo(`/drawe?level=${JSON.stringify(level)}`)
|
||||
navigateTo(`/drawe/${primary.id}/1/12/-1`)
|
||||
}
|
||||
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
<div
|
||||
class="left mt-[25px] box-border h-[370px] w-[260px] border border-[#EEEEEE] rounded-[4px] border-solid bg-[#FFFFFF] text-[15px] text-[#333333] font-medium"
|
||||
>
|
||||
<nuxt-link to="/personal-Center/info" class="flex items-center justify-between py-[14px]">
|
||||
<nuxt-link to="/personal-center/info" class="flex items-center justify-between py-[14px]">
|
||||
<div class="flex items-center pl-[20px]">
|
||||
<img v-if="route.path.startsWith('/personal-Center/info')" src="~/assets/images/user3.png" alt="" srcset="" class="h-[20px]" />
|
||||
<img v-if="route.path.startsWith('/personal-center/info')" src="~/assets/images/user3.png" alt="" srcset="" class="h-[20px]" />
|
||||
<img v-else src="~/assets/images/个人.png" alt="" srcset="" class="h-[20px]" />
|
||||
<span class="ml-[10px]">个人中心</span>
|
||||
</div>
|
||||
@ -15,9 +15,9 @@
|
||||
</div>
|
||||
</nuxt-link>
|
||||
|
||||
<!-- <nuxt-link to="/personal-Center/personal-profile" class="flex items-center justify-between py-[14px]">
|
||||
<!-- <nuxt-link to="/personal-center/personal-profile" class="flex items-center justify-between py-[14px]">
|
||||
<div class="flex items-center pl-[20px]">
|
||||
<img v-if="!route.path.startsWith('/personal-Center/personal-profile')" src="~/assets/images/user_zl.png" alt="" srcset="" class="h-[16px]" />
|
||||
<img v-if="!route.path.startsWith('/personal-center/personal-profile')" src="~/assets/images/user_zl.png" alt="" srcset="" class="h-[16px]" />
|
||||
<img v-else src="~/assets/images/个人资料 (1).png" alt="" srcset="" class="h-[16px]" />
|
||||
<span class="ml-[10px]">个人资料</span>
|
||||
</div>
|
||||
@ -25,9 +25,9 @@
|
||||
<el-icon><ArrowRight /></el-icon>
|
||||
</div>
|
||||
</nuxt-link>
|
||||
<nuxt-link to="/personal-Center/account-security" class="flex items-center justify-between py-[14px]">
|
||||
<nuxt-link to="/personal-center/account-security" class="flex items-center justify-between py-[14px]">
|
||||
<div class="flex items-center pl-[20px]">
|
||||
<img v-if="!route.path.startsWith('/personal-Center/account-security')" src="~/assets/images/account.png" alt="" srcset="" class="h-[20px]" />
|
||||
<img v-if="!route.path.startsWith('/personal-center/account-security')" src="~/assets/images/account.png" alt="" srcset="" class="h-[20px]" />
|
||||
<img v-else src="~/assets/images/账户安全.png" alt="" srcset="" class="h-[20px]" />
|
||||
<span class="ml-[14px]">账户与安全</span>
|
||||
</div>
|
||||
@ -35,9 +35,9 @@
|
||||
<el-icon><ArrowRight /></el-icon>
|
||||
</div>
|
||||
</nuxt-link> -->
|
||||
<nuxt-link to="/personal-Center/account-management" class="flex items-center justify-between py-[14px]">
|
||||
<nuxt-link to="/personal-center/account-management" class="flex items-center justify-between py-[14px]">
|
||||
<div class="flex items-center pl-[20px]">
|
||||
<img v-if="!route.path.startsWith('/personal-Center/account-management')" src="~/assets/images/account.png" alt="" srcset="" class="h-[20px]" />
|
||||
<img v-if="!route.path.startsWith('/personal-center/account-management')" src="~/assets/images/account.png" alt="" srcset="" class="h-[20px]" />
|
||||
<img v-else src="~/assets/images/账户安全.png" alt="" srcset="" class="h-[20px]" />
|
||||
<span class="ml-[14px]">账户管理</span>
|
||||
</div>
|
||||
@ -45,9 +45,9 @@
|
||||
<el-icon><ArrowRight /></el-icon>
|
||||
</div>
|
||||
</nuxt-link>
|
||||
<nuxt-link to="/personal-Center/resource-center" class="flex items-center justify-between py-[14px]">
|
||||
<nuxt-link to="/personal-center/resource-center" class="flex items-center justify-between py-[14px]">
|
||||
<div class="flex items-center pl-[20px]">
|
||||
<img v-if="!route.path.startsWith('/personal-Center/resource-center')" src="~/assets/images/ziyuan.png" alt="" srcset="" class="h-[18px]" />
|
||||
<img v-if="!route.path.startsWith('/personal-center/resource-center')" src="~/assets/images/ziyuan.png" alt="" srcset="" class="h-[18px]" />
|
||||
<img v-else src="~/assets/images/资源.png" alt="" srcset="" class="h-[18px]" />
|
||||
<span class="ml-[12px]">资源中心</span>
|
||||
</div>
|
||||
@ -55,19 +55,19 @@
|
||||
<el-icon><ArrowRight /></el-icon>
|
||||
</div>
|
||||
</nuxt-link>
|
||||
<nuxt-link to="/personal-Center/trading-center" class="flex items-center justify-between py-[14px]">
|
||||
<nuxt-link to="/personal-center/trading-center" class="flex items-center justify-between py-[14px]">
|
||||
<div class="flex items-center pl-[20px]">
|
||||
<img v-if="!route.path.startsWith('/personal-Center/trading-center')" src="~/assets/images/pay.png" alt="" srcset="" class="h-[20px]" />
|
||||
<img v-if="!route.path.startsWith('/personal-center/trading-center')" src="~/assets/images/pay.png" alt="" srcset="" class="h-[20px]" />
|
||||
<img v-else src="~/assets/images/交易管理.png" alt="" srcset="" class="h-[20px]" />
|
||||
<span class="ml-[12px]">交易中心</span>
|
||||
<span class="ml-[12px]">交易记录</span>
|
||||
</div>
|
||||
<div class="pr-[20px]">
|
||||
<el-icon><ArrowRight /></el-icon>
|
||||
</div>
|
||||
</nuxt-link>
|
||||
<nuxt-link to="/personal-Center/message-center" class="flex items-center justify-between py-[14px]">
|
||||
<nuxt-link to="/personal-center/message-center" class="flex items-center justify-between py-[14px]">
|
||||
<div class="flex items-center pl-[20px]">
|
||||
<img v-if="!route.path.startsWith('/personal-Center/message-center')" src="~/assets/images/message.png" alt="" srcset="" class="h-[18px]" />
|
||||
<img v-if="!route.path.startsWith('/personal-center/message-center')" src="~/assets/images/message.png" alt="" srcset="" class="h-[18px]" />
|
||||
<img v-else src="~/assets/images/消息.png" alt="" srcset="" class="h-[18px]" />
|
||||
<span class="ml-[14px]">消息通知</span>
|
||||
</div>
|
||||
|
||||
@ -17,7 +17,14 @@
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination mt-15px">
|
||||
<el-pagination v-model:current-page="query.pageNo" :page-size="10" :total="result.total" background layout="prev, pager, next, jumper" />
|
||||
<el-pagination
|
||||
v-model:current-page="query.pageNo"
|
||||
:page-size="10"
|
||||
:total="result.total"
|
||||
background
|
||||
layout="prev, pager, next, jumper"
|
||||
@current-change="handeClickCurrent"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -51,6 +58,12 @@
|
||||
}
|
||||
}
|
||||
getTradeRecords()
|
||||
|
||||
// 点击分页
|
||||
const handeClickCurrent = (pageNo: number) => {
|
||||
query.pageNo = pageNo
|
||||
getTradeRecords()
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-pagination) {
|
||||
|
||||
@ -11,12 +11,12 @@
|
||||
<!-- <div class="vip-card-subtitle">中小微企业</div> -->
|
||||
</div>
|
||||
<div class="vip-card-price">
|
||||
<span class="price">¥{{ accDiv(item.payPrice || 0, 100) }}</span>
|
||||
<span class="price">¥{{ item.payPrice }}</span>
|
||||
<!-- <span class="per">/1年</span> -->
|
||||
</div>
|
||||
<ul class="vip-card-features">
|
||||
<li
|
||||
>赠送<span class="color-red">¥{{ accDiv(item.bonusPrice || 0, 100) }}</span></li
|
||||
>赠送<span class="color-red">¥{{ item.bonusPrice }}</span></li
|
||||
>
|
||||
<!-- <li>1. {{ item.profile }}</li>
|
||||
<li
|
||||
@ -39,7 +39,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, onMounted } from 'vue'
|
||||
import { listWalletRechargePackage, submitPayOrder, getPayStatus } from '~/api/pay/index'
|
||||
import { accDiv } from '~/utils/utils'
|
||||
// import { accDiv } from '~/utils/utils'
|
||||
import { Close } from '@element-plus/icons-vue'
|
||||
import type { AppPayWalletPackageRespVO } from '~/api/pay/types'
|
||||
// @ts-ignore
|
||||
@ -155,8 +155,10 @@
|
||||
.vip-cards {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
justify-content: center;
|
||||
/* justify-content: center; */
|
||||
margin: 24px 0;
|
||||
overflow-x: auto;
|
||||
padding: 10px;
|
||||
}
|
||||
.vip-card {
|
||||
background: #fff;
|
||||
@ -169,6 +171,7 @@
|
||||
align-items: center;
|
||||
padding-bottom: 70px;
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.vip-card-header {
|
||||
width: 100%;
|
||||
|
||||
@ -125,7 +125,7 @@
|
||||
fetchUserStatistics()
|
||||
|
||||
const handleClick = () => {
|
||||
router.push({ path: '/personal-Center/account-management' })
|
||||
router.push({ path: '/personal-center/account-management' })
|
||||
}
|
||||
|
||||
const payVisible = ref(false)
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
<template>
|
||||
<div class="account-balance">
|
||||
<!-- 余额展示区域 -->
|
||||
<div class="balance-section">
|
||||
<div class="balance-section flex h-206px!">
|
||||
<div>
|
||||
<div class="balance-title">
|
||||
<span>我的金币(元)</span>
|
||||
<el-tag size="small" type="primary">资产和使用</el-tag>
|
||||
@ -9,16 +10,40 @@
|
||||
<div class="balance-amount">{{ userStaticInfo?.currencyCount || 0 }}</div>
|
||||
<div class="balance-actions">
|
||||
<el-button type="primary" @click="handlePay">充值</el-button>
|
||||
<el-button>提现</el-button>
|
||||
<el-button type="danger" @click="handleWithdraw">提现</el-button>
|
||||
<el-button type="warning">兑换</el-button>
|
||||
</div>
|
||||
<div class="balance-tip">提示:最低提现金额:100 元,一元=10金币</div>
|
||||
</div>
|
||||
<el-divider direction="vertical" class="h-100%! mx-30px!" border-style="dashed"></el-divider>
|
||||
<div>
|
||||
<div class="balance-title">
|
||||
<span>我的收益</span>
|
||||
<el-tag size="small" type="primary">收益金币数额展示</el-tag>
|
||||
</div>
|
||||
<div class="balance-amount">{{ userStaticInfo?.revenueBalance || 0 }}</div>
|
||||
<div class="balance-actions">
|
||||
<!-- <el-button type="primary" @click="handlePay">充值</el-button>
|
||||
<el-button>提现</el-button> -->
|
||||
</div>
|
||||
<!-- <div class="balance-tip">提示:最低提现金额:100 元,一元=10金币</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- 广告海报swiper -->
|
||||
<el-carousel height="150px" class="rounded-[8px] rounded-[6px] border border-solid border-[#eeeeee] box-borders mb-20px">
|
||||
<el-carousel-item>
|
||||
<el-image src="https://static.tuxixi.net/tuxixi_banner3.png" alt="" class="w-100%" fit="contain" />
|
||||
</el-carousel-item>
|
||||
<el-carousel-item>
|
||||
<el-image src="https://static.tuxixi.net/tuxixi_banner2.jpg" alt="" class="w-100%" fit="cover" />
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
|
||||
<!-- 交易记录区域 -->
|
||||
<div class="transaction-section">
|
||||
<div class="transaction-tabs">
|
||||
<el-tabs v-model="activeTab">
|
||||
<el-tab-pane label="充值记录" name="purchase">
|
||||
<el-tab-pane label="交易记录" name="purchase">
|
||||
<!-- 组件 -->
|
||||
<PayRecords></PayRecords>
|
||||
</el-tab-pane>
|
||||
@ -32,8 +57,14 @@
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- 提示 -->
|
||||
<div class="color-red pa-10px text-13px">
|
||||
温馨提示:交易未到账紧急联系客服,金币为虚拟积分不支持退款,但支持高额手续费提现,抵制恶性充值提现操作,金币使用没有时间限制,平台作品交易仅供学习参考,用于商业用途请与原作者联系!
|
||||
</div>
|
||||
<!-- 充值弹窗 -->
|
||||
<Pay v-if="payVisible" v-model="payVisible" @refresh="fetchUserStatistics"></Pay>
|
||||
<!-- 提现弹窗 -->
|
||||
<Withdraw v-if="withdrawVisible" v-model="withdrawVisible"></Withdraw>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -60,6 +91,12 @@
|
||||
payVisible.value = true
|
||||
// router.push({ path: '/personal/trading/center' })
|
||||
}
|
||||
|
||||
const withdrawVisible = ref(false)
|
||||
const handleWithdraw = () => {
|
||||
withdrawVisible.value = true
|
||||
// router.push({ path: '/personal/trading/center' })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@ -1,57 +1,338 @@
|
||||
<!-- 工具箱详情页面 -->
|
||||
<template>
|
||||
<SeoHead :title="detail?.title" :description="detail?.description" :keywords="detail?.labels?.toString()" />
|
||||
<KlNavTab />
|
||||
<!-- <div v-if="breadList && breadList.length > 1" class="mb-[-10px] mt-[20px] w-[1440px] mx-auto">
|
||||
<el-breadcrumb :separator-icon="ArrowRight">
|
||||
<el-breadcrumb-item v-for="(item, index) in breadList" :key="item.name">{{ item.name }}</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div> -->
|
||||
<div class="ml-auto mr-auto mt-[20px] w-[1440px]">
|
||||
<div class="flex items-center">
|
||||
<div
|
||||
class="toolbox-detail w-[1200px] min-h-[374px] bg-[#FFFFFF] rounded-[12px] border border-solid border-[#EEEEEE] pa-[37px] pt-[20px] box-border ma-auto mt-[30px]"
|
||||
class="box-border h-[60px] w-[1019px] flex items-center justify-between border border-[#EEEEEE] rounded-[12px] border-solid bg-[#FFFFFF] px-[27px] py-[24px]"
|
||||
>
|
||||
<div class="w-[100%]">
|
||||
<h1 class="font-[Microsoft_YaHei] font-bold text-[24px] text-[#333333] leading-[21px]">{{ detail?.title }}</h1>
|
||||
<div class="flex items-center w-[100%] mt-[30px]">
|
||||
<img :src="userStore.ownedUserAvatar" alt="头像" class="w-[49px] h-[50px] rounded-[50%] mr-[16px]" />
|
||||
<div class="flex flex-col items-start w-[100%]">
|
||||
<p class="font-[Microsoft_YaHei] font-normal text-[16px] text-[#333333] leading-[8px]">{{ userStore.ownedUserName || '用户昵称' }}</p>
|
||||
<div class="flex items-center justify-between mt-[8px] w-[100%]">
|
||||
<p class="font-[Microsoft_YaHei] font-normal text-[12px] text-[#999999] leading-[8px]">
|
||||
{{ dayjs(detail?.createTime).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</p>
|
||||
<div class="flex items-center justify-between font-[Microsoft_YaHei] font-normal text-[14px] text-[#666666] leading-[8px]">
|
||||
<div class="mr-[9px] flex items-center">
|
||||
<img src="~/assets/images/look.png" alt="" srcset="" class="mr-[2px] h-[17px]" />
|
||||
<span class="color-[#666]">{{ detail?.previewPoint || 0 }}</span>
|
||||
<div class="text-[16px] text-[#333333] font-normal"> {{ detail?.title }}</div>
|
||||
<div class="flex items-center">
|
||||
<img :src="detail?.ownedUserAvatar" alt="" srcset="" class="h-[30px] w-[30px] rd-[50%]" />
|
||||
<span class="ml-[8px] color-[#999999]">by {{ detail?.ownedUserName }}</span>
|
||||
</div>
|
||||
<div class="mr-[9px] flex items-center">
|
||||
<img src="~/assets/images/add.png" alt="" srcset="" class="mr-[2px] h-[22px]" />
|
||||
<span class="color-[#666]">{{ detail?.hotPoint || 0}}</span>
|
||||
</div>
|
||||
|
||||
<div class="ml-[23px] flex flex-1 text-[16px] text-[#FFFFFF] font-normal">
|
||||
<div class="h-[60px] w-[160px] flex cursor-pointer items-center justify-center rounded-[8px] bg-[#1A65FF]" @click="handleDownload">
|
||||
<img src="~/assets/images/download.png" alt="" srcset="" class="mr-[4px] h-[22px] w-[27px]" />
|
||||
{{ detail?.points === 0 ? '免费下载' : '立即下载' }}
|
||||
</div>
|
||||
<div
|
||||
v-if="!detail?.favoriteId"
|
||||
class="ml-[11px] h-[60px] flex flex-1 cursor-pointer items-center justify-center rounded-[8px] bg-[#E7B03B]"
|
||||
@click="handleCollect"
|
||||
><img src="~/assets/images/collect.png" alt="" srcset="" class="mr-[4px] h-[24px] w-[24px]" /> 收藏</div
|
||||
>
|
||||
<div v-else class="ml-[11px] h-[60px] flex flex-1 cursor-pointer items-center justify-center rounded-[8px] bg-[#E7B03B]" @click="handleCollect"
|
||||
><img src="~/assets/images/wjx2.png" alt="" srcset="" class="mr-[4px] h-[18px] w-[18px]" /> 已收藏</div
|
||||
>
|
||||
|
||||
<div class="ml-[11px] h-[60px] flex flex-1 cursor-pointer items-center justify-center rounded-[8px] bg-[#F56C6C]" @click="handleReport"
|
||||
><el-icon class="mr-[4px] mt-[4px]"><Warning /></el-icon> 举报</div
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- -->
|
||||
<div class="ma-auto mt-[21px] flex">
|
||||
<div class="w-[1019px]">
|
||||
<div>
|
||||
<ThumBnail :data="detail?.coverImages"></ThumBnail>
|
||||
</div>
|
||||
<div class="mb-[20px] mt-[34px] flex items-center text-[14px] text-[#333333] font-normal">
|
||||
<div class="h-[20px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div><span class="ml-[10px]">工具使用介绍</span></div
|
||||
>
|
||||
<div
|
||||
class="box-border min-h-[90px] w-[1019px] border border-[#EEEEEE] rounded-[6px] border-solid bg-[#FFFFFF] pa-[24px] text-[14px] text-[#333333] font-normal"
|
||||
>
|
||||
{{ detail?.description }}
|
||||
</div>
|
||||
<div id="section1" class="mb-[20px] mt-[34px] flex items-center text-[14px] text-[#333333] font-normal">
|
||||
<div class="h-[20px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div><span class="ml-[10px]">工具文件</span></div
|
||||
>
|
||||
<div class="box-border w-[1019px] border border-[#EEEEEE] rounded-[6px] border-solid bg-[#FFFFFF] pa-[24px]">
|
||||
<div class="border-b-[1px] border-b-[#eee] border-b-solid p-b-[10px]"> 包含的文件 </div>
|
||||
<div>
|
||||
<div v-for="item in detail?.files" :key="item.id" class="flex items-center justify-between border-b-[1px] border-b-[#eee] border-b-solid py-[10px]">
|
||||
<!-- <img src="~/assets/images/avater.png" alt="" srcset="" class="h-30px w-30px" /> -->
|
||||
<div>
|
||||
<!-- <span class="ml-[10px] cursor-pointer" @click="handleDownloadPreview(item)">{{ item.title }}</span> -->
|
||||
<span class="ml-[10px]">{{ item.title }}</span>
|
||||
<span v-if="item.size" class="ml-[200px] color-[#999]">{{ item.size || '-' }}</span>
|
||||
</div>
|
||||
<el-button
|
||||
v-if="detail?.downloadId || detail?.points === 0"
|
||||
type="text"
|
||||
tag="a"
|
||||
target="download"
|
||||
:href="item.url"
|
||||
@click="handleDownloadFile(item.url, item.title)"
|
||||
>
|
||||
下载
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 评论 -->
|
||||
<CommentSection :relation-id="detail!.id" />
|
||||
</div>
|
||||
<div class="ml-[22px]">
|
||||
<div class="box-border min-h-[180px] w-[397px] border border-[#EEEEEE] rounded-[12px] border-solid bg-[#FFFFFF] pa-[22px]">
|
||||
<div class="mb-[10px]">工具ID: {{ detail?.no }}</div>
|
||||
<!-- <div class="mb-[10px]">文件大小:{{ detail?.filesInfo?.fileSize || 0 }} </div> -->
|
||||
<!-- <div class="mb-10px">图纸版本:{{ detail.editionsName }} </div> -->
|
||||
<!-- <div class="mb-[10px]">工具格式:{{ detail?.formatType?.toString() }}</div> -->
|
||||
<div class="mb-[10px]">所需金币:{{ detail?.points }}金币</div>
|
||||
<div class="mb-[10px]">发布时间:{{ dayjs(detail?.createTime).format('YYYY-MM-DD HH:mm:ss') }}</div>
|
||||
<!-- <div class="mb-[10px]">工具参数:{{ detail?.editTypeName }}</div> -->
|
||||
<div class="mb-[10px]">工具标签:{{ detail?.labels?.toString() }}</div>
|
||||
<div class="mb-[10px]">软件分类:{{ detail?.categoryName }}</div>
|
||||
</div>
|
||||
<div class="mt-[20px] w-[398px] border border-[#EEEEEE] border-rd-[10px_10px_0px_0px] border-solid bg-[#FFFFFF]">
|
||||
<img src="~/assets/images/banner.png" alt="" srcset="" class="w-[100%]" />
|
||||
<div class="box-border border border-[#EEEEEE] border-rd-[10px_10px_0px_0px] border-solid border-t-none bg-[#FFFFFF] pa-[18px]">
|
||||
<div class="flex flex-wrap items-start">
|
||||
<div v-if="userInfo?.nickname" class="text-[18px] text-[#333333] font-bold">{{ userInfo.nickname }}</div>
|
||||
<div
|
||||
v-for="item in userInfo?.labels"
|
||||
:key="item"
|
||||
class="mb-[10px] ml-[10px] box-border border border-[#1A65FF] rounded-[13px] border-solid px-[8px] py-[3px] color-[#1a65ff]"
|
||||
>{{ item }}</div
|
||||
>
|
||||
</div>
|
||||
<div v-if="userInfo?.description" class="mb-[20px] text-[14px] text-[#333333] font-normal">{{ userInfo.description }}</div>
|
||||
<!-- 显示作品 粉丝 荣誉证书 -->
|
||||
<div class="flex items-center gap-[40px]">
|
||||
<div class="flex items-center">
|
||||
<div class="h-[20px]">
|
||||
<img src="~/assets/images/folder.png" alt="works" class="w-[80%]" />
|
||||
</div>
|
||||
<div class="ml-[8px] mt-[-4px] text-[14px] text-[#666] font-normal">作品: {{ userInfo?.projectCount || 0 }}</div>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<img src="~/assets/images/chat.png" alt="" srcset="" class="mr-[4px] h-[17px]" />
|
||||
<span class="color-[#666]">{{ detail?.commentsPoint || 0 }}</span>
|
||||
<div class="h-[20px]">
|
||||
<img src="~/assets/images/user4.png" alt="fans" class="w-[80%] rounded-full vertical-top" />
|
||||
</div>
|
||||
<div class="relative top-[-3px] ml-[8px] text-[14px] text-[#666] font-normal">发帖数: {{ userInfo?.fansCount || 0 }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3个图片一排 超过换下一行 -->
|
||||
<div v-if="userInfo?.files?.length" class="mt-[20px] flex flex-wrap gap-[16px]">
|
||||
<div v-for="i in userInfo.files" :key="i" class="flex-1">
|
||||
<div
|
||||
class="box-border h-[200px] w-full overflow-hidden border border-[#E5E7EB] rounded-[8px] border-solid from-[#FFFFFF] to-[#F5F7FA] bg-gradient-to-b p-[16px]"
|
||||
>
|
||||
<el-image :src="i.url" fit="cover" alt="" srcset="" class="h-full object-cover" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-[20px] h-[1px] w-[336px] rounded-[1px] bg-[#EEEEEE]"></div>
|
||||
<div class="mt-[20px] flex items-center">
|
||||
<div class="h-[20px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div>
|
||||
<span class="ml-[10px] text-[14px]">最新发布</span>
|
||||
</div>
|
||||
<div class="mt-[10px]">
|
||||
<div
|
||||
v-for="item in mainWork"
|
||||
:key="item.id"
|
||||
class="flex cursor-pointer items-center justify-between px-[10px] py-[10px] hover:bg-[#f5f5f5]"
|
||||
@click="handleClick(item.id)"
|
||||
>
|
||||
<div class="ellipsis text-[15px] text-[#333333] font-normal">{{ item.title }}</div>
|
||||
<span class="ml-[10px] flex-shrink-0 color-[#999999]">{{ dayjs(item.createTime).format('MM-DD') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-[100%] h-[1px] bg-[#EEEEEE] rounded-[1px] my-[20px]"></div>
|
||||
<div class="body">
|
||||
<p class="font-[Microsoft_YaHei] font-normal text-[14px] text-[#333333] leading-[26px]">
|
||||
{{ detail?.description }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import dayjs from 'dayjs'
|
||||
import { ArrowRight } from '@element-plus/icons-vue'
|
||||
import { downloadFile } from '~/utils/utils'
|
||||
import { useMessage } from '~/utils/useMessage'
|
||||
import { Warning } from '@element-plus/icons-vue'
|
||||
import SeoHead from '~/components/seo-head/index.vue'
|
||||
import CardPicture from '~/components/kl-card-picture/index.vue'
|
||||
import { getDictTree } from '~/api/home/index'
|
||||
import { get } from '@/api/toolbox/index'
|
||||
import { getDetail, getRelationRecommend, report, getToolUserInfo, getMainWork, createContent, createUserProject, deleteProject } from '~/api/drawe-detail/index'
|
||||
import KlNavTab from '~/components/kl-nav-tab/index.vue'
|
||||
import ThumBnail from './components/swiper.vue'
|
||||
import CommentSection from '~/components/comment-section/index.vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import useUserStore from '~/stores/user'
|
||||
const message = useMessage()
|
||||
const userStore = useUserStore()
|
||||
// 获取路由参数
|
||||
const route = useRoute()
|
||||
console.log(route.params.id)
|
||||
const id = route.params.id as string
|
||||
|
||||
const { data: detail } = await useAsyncData(`toolbox-detail-${route.params.id}}`, async () => {
|
||||
const res = await get({ id: route.params.id as string })
|
||||
const { data: detail, refresh: refreshDetail } = await useAsyncData(`toolbox-getDetail${id}`, async () => {
|
||||
const res = await get({ id: id as string })
|
||||
return res.data
|
||||
})
|
||||
|
||||
console.log(detail.value)
|
||||
console.log('==', detail.value)
|
||||
|
||||
if (!detail.value) {
|
||||
throw createError({
|
||||
statusCode: 404,
|
||||
statusMessage: 'Page Not Found',
|
||||
fatal: true,
|
||||
})
|
||||
}
|
||||
|
||||
// init()
|
||||
|
||||
const [{ data: mainWork }, { data: userInfo }] = await Promise.all([
|
||||
getMainWork({ id: detail.value?.id, limit: 10, memberId: detail.value?.ownedUserId }),
|
||||
getToolUserInfo({ id: detail.value?.id }),
|
||||
])
|
||||
|
||||
// 获取最新发布
|
||||
// const mainWork = ref<ProjectDrawMemberRespVO[]>([])
|
||||
// const handleGetMainWork = () => {
|
||||
// getMainWork({ id: detail.value?.id, limit: 10, memberId: detail.value?.ownedUserId }).then((res) => {
|
||||
// if (res.code === 0) {
|
||||
// mainWork.value = res.data
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// 获取用户信息
|
||||
// const userInfo = ref<UserExtendSimpleRespDTO>({} as UserExtendSimpleRespDTO)
|
||||
// const handleGetUserInfo = () => {
|
||||
// getUserInfo({ id: detail.value?.id }).then((res) => {
|
||||
// if (res.code === 0) {
|
||||
// userInfo.value = res.data
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
// 获取关联推荐
|
||||
// const relationRecommend = ref<ProjectDrawPageRespVO[]>([])
|
||||
// const getRelationRecommendList = () => {
|
||||
// getRelationRecommend({ type: detail.value?.type, projectType: detail.value?.projectType[0] }).then((res) => {
|
||||
// if (res.code === 0) {
|
||||
// relationRecommend.value = res.data
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
const handleDownloadPreview = (item: any) => {
|
||||
// 预览pdf
|
||||
navigateTo(`/pdf-preview?url=${item.url}`)
|
||||
}
|
||||
|
||||
/** 获取下载类型 */
|
||||
const getType = (type: number) => {
|
||||
if (type === 1 || type === 2 || type === 3) {
|
||||
// 图纸 文本 模型都传1
|
||||
return 1
|
||||
}
|
||||
// 工具箱传
|
||||
return 2
|
||||
}
|
||||
|
||||
const handleDownload = async () => {
|
||||
if (!userStore.token) {
|
||||
ElMessage.error('请先登录')
|
||||
return
|
||||
}
|
||||
|
||||
if (detail.value?.points === 0) {
|
||||
scrollTo()
|
||||
return
|
||||
}
|
||||
|
||||
if (detail.value?.downloadId) {
|
||||
ElMessage.success('您已获取下载权限')
|
||||
scrollTo()
|
||||
return
|
||||
}
|
||||
|
||||
const res = await message.confirm(`是否花费${detail.value?.points}金币下载此资源,是否继续?`, '提示')
|
||||
if (res) {
|
||||
createUserProject({ relationId: detail.value?.id, type: 2 }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
ElMessage.success('获取下载权限成功')
|
||||
detail.value!.downloadId = res.data
|
||||
scrollTo()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const scrollTo = () => {
|
||||
const element = document.getElementById('section1')
|
||||
if (element) {
|
||||
element.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const handleReport = () => {
|
||||
if (!userStore.token) {
|
||||
ElMessage.error('请先登录')
|
||||
return
|
||||
}
|
||||
console.log('举报')
|
||||
ElMessageBox.prompt('说明内容', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
inputPlaceholder: '请输入举报内容',
|
||||
inputErrorMessage: '请输入举报内容',
|
||||
}).then(({ value }) => {
|
||||
report({
|
||||
id: detail.value?.id,
|
||||
title: detail.value?.title,
|
||||
files: detail.value?.files,
|
||||
comments: value,
|
||||
drawId: detail.value?.id,
|
||||
type: 4,
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
ElMessage.success('举报成功')
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const handleCollect = async () => {
|
||||
if (!userStore.token) {
|
||||
ElMessage.error('请先登录')
|
||||
return
|
||||
}
|
||||
|
||||
const res = detail.value?.favoriteId
|
||||
? await deleteProject({ id: detail.value.favoriteId })
|
||||
: await createContent({
|
||||
drawId: detail.value?.id,
|
||||
type: 4,
|
||||
})
|
||||
if (res.code === 0) {
|
||||
ElMessage.success(`${detail.value?.favoriteId ? '取消' : '收藏'}成功`)
|
||||
refreshDetail()
|
||||
}
|
||||
}
|
||||
|
||||
const handleClick = (id: string | number) => {
|
||||
navigateTo(`/toolbox-detail/${id}`) // 修改为在新窗口打开
|
||||
}
|
||||
|
||||
const handleDownloadFile = (url: string, name: string) => {
|
||||
downloadFile(url, name)
|
||||
}
|
||||
</script>
|
||||
|
||||
163
pages/toolbox-detail/components/swiper.vue
Normal file
163
pages/toolbox-detail/components/swiper.vue
Normal file
@ -0,0 +1,163 @@
|
||||
<template>
|
||||
<div class="box-border h-[631px] w-[1019px] border border-[#EEEEEE] rounded-[12px] border-solid bg-[#FFFFFF] pa-[30px]">
|
||||
<div style="--swiper-navigation-color: #fff; --swiper-pagination-color: #fff" class="swiper mySwiper2">
|
||||
<div class="swiper-wrapper">
|
||||
<div class="swiper-slide" v-for="(item, index) in props.data" :key="index">
|
||||
<img :src="item.url" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="swiper-button-next"></div>
|
||||
<div class="swiper-button-prev"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-[20px] mt-[34px] flex items-center text-[14px] text-[#333333] font-normal">
|
||||
<div class="h-[20px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div>
|
||||
<span class="ml-[10px]">工具截图</span>
|
||||
</div>
|
||||
<div class="box-border h-[126px] w-[1019px] border border-[#EEEEEE] rounded-[6px] border-solid bg-[#FFFFFF] pa-[23px]">
|
||||
<div thumbsSlider="" class="swiper mySwiper">
|
||||
<div class="swiper-wrapper">
|
||||
<div class="swiper-slide" v-for="(item, index) in props.data" :key="index">
|
||||
<img :src="item.url" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import type { PropType } from 'vue'
|
||||
import { ref, watch, nextTick, onMounted } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Array as PropType<any[]>,
|
||||
default: () => [],
|
||||
},
|
||||
type: {
|
||||
type: Number as PropType<number>,
|
||||
default: 1,
|
||||
},
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
// Initialize Swiper
|
||||
// @ts-ignore
|
||||
var swiper = new Swiper('.mySwiper', {
|
||||
spaceBetween: 10,
|
||||
slidesPerView: 4,
|
||||
freeMode: true,
|
||||
watchSlidesProgress: true,
|
||||
})
|
||||
// @ts-ignore
|
||||
var swiper2 = new Swiper('.mySwiper2', {
|
||||
spaceBetween: 10,
|
||||
navigation: {
|
||||
nextEl: '.swiper-button-next',
|
||||
prevEl: '.swiper-button-prev',
|
||||
},
|
||||
thumbs: {
|
||||
swiper: swiper,
|
||||
},
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.swiper-button-disabled {
|
||||
cursor: pointer !important;
|
||||
}
|
||||
.swiper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.swiper-slide {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
background: #fff;
|
||||
|
||||
/* Center slide text vertically */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.swiper-slide img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.swiper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.swiper-slide {
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.mySwiper2 {
|
||||
height: 100%;
|
||||
/* height: calc(100vh - 207px); */
|
||||
/* width: 100%; */
|
||||
}
|
||||
|
||||
.mySwiper {
|
||||
height: 90px;
|
||||
box-sizing: border-box;
|
||||
padding: 6px 6px;
|
||||
|
||||
/* position: absolute;
|
||||
bottom: 0;
|
||||
left: 0px;
|
||||
right: 0px !important; */
|
||||
background: rgba(0, 0, 0, 0.65);
|
||||
|
||||
/* z-index: 1000; */
|
||||
|
||||
/* width: 100%; */
|
||||
}
|
||||
|
||||
.mySwiper .swiper-slide {
|
||||
width: 25%;
|
||||
height: 100%;
|
||||
opacity: 0.4;
|
||||
background: rgba(0, 0, 0, 0.65);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mySwiper .swiper-slide-thumb-active {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.swiper-slide img {
|
||||
display: block;
|
||||
/* width: 100%; */
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.Thumbs {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: auto;
|
||||
background: rgba(0, 0, 0, 0.65);
|
||||
}
|
||||
|
||||
.Thumbs img {
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.swiper-button-next,
|
||||
.swiper-button-prev {
|
||||
color: #666 !important;
|
||||
}
|
||||
</style>
|
||||
@ -2,33 +2,17 @@
|
||||
<KlNavTab active="工具箱" />
|
||||
<!-- 搜索 -->
|
||||
<KlSearch @search="search"></KlSearch>
|
||||
<div v-loading="loading" class="ma-auto mt-[20px] w-[1440px] flex justify-center gap-[60px]">
|
||||
<div class="left w-[821px]">
|
||||
<!-- <img src="~/assets/images/banner2.png" alt="" srcset="" class="h-[284px] w-[100%]" /> -->
|
||||
<el-form ref="formRef" :model="pageReq" label-width="110px" size="large" inline>
|
||||
<el-form-item label-width="110px" label="软件分类:" prop="categoryId" :rules="{ required: true, message: '请选择分类', trigger: ['blur', 'change'] }">
|
||||
<!-- <el-select v-model="form.categoryId" placeholder="请选择软件分类" class="w-[361px]!" multiple>
|
||||
<el-option v-for="(item, index) in projectTypeList" :key="index" :label="item.name" :value="item.id" />
|
||||
</el-select> -->
|
||||
<el-cascader
|
||||
v-model="pageReq.categoryId"
|
||||
class="w-[280px]!"
|
||||
:options="projectTypeList"
|
||||
:props="cascaderProps"
|
||||
clearable
|
||||
collapse-tags
|
||||
@change="handleCurrentChange(1)"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label-width="110px" label="分类:" prop="sourceType" :rules="{ required: true, message: '请选择', trigger: ['blur', 'change'] }">
|
||||
<el-radio-group v-model="pageReq.sourceType" @change="handleCurrentChange(1)">
|
||||
<el-radio :label="0">原创开发</el-radio>
|
||||
<el-radio :label="1">转载分享</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="box-border border border-[#EEEEEE] rounded-[12px] border-solid bg-[#FFFFFF] px-[28px] py-[17px]">
|
||||
<div @click="handleClick(item)" v-for="item in pageRes?.list" :key="item.id" class="mt-[20px] flex border-b-[1px] border-b-[#eee] border-b-solid pb-[20px] cursor-pointer">
|
||||
<div v-loading="loading" class="ma-auto mt-[20px] w-[1440px] flex justify-between">
|
||||
<div class="left w-[1000px]">
|
||||
<KlWallpaperCategory v-model="pageReq.categoryId" />
|
||||
<KlTabBar v-model="pageReq.sourceType" :data="tabBar" class="mt-[20px]" />
|
||||
<div class="mt-[4px] box-border border border-[#EEEEEE] rounded-[12px] border-solid bg-[#FFFFFF] px-[28px] py-[17px]" v-loading="loading">
|
||||
<div
|
||||
@click="handleClick(item)"
|
||||
v-for="item in pageRes?.list"
|
||||
:key="item.id"
|
||||
class="mt-[20px] flex border-b-[1px] border-b-[#eee] border-b-solid pb-[20px] cursor-pointer"
|
||||
>
|
||||
<div class="h-[142px] w-[200px] text-center">
|
||||
<el-image :src="item.iconUrl" alt="" srcset="" class="max-w-[100%] rd-[4px]" fit="cover" />
|
||||
</div>
|
||||
@ -68,7 +52,7 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right w-[398px]">
|
||||
<div class="right w-[400px]">
|
||||
<div class="box-border border border-[#EEEEEE] rounded-[10px] border-solid bg-[#FFFFFF] pa-[16px]">
|
||||
<div class="flex items-center text-[14px] text-[#333333] font-normal">
|
||||
<div class="mr-[14px] h-[16px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div>
|
||||
@ -76,36 +60,6 @@
|
||||
</div>
|
||||
<div v-for="item in recommendList" :key="item.id" class="mt-[20px] text-[14px] text-[#666] font-normal">{{ item.title }}</div>
|
||||
</div>
|
||||
<!-- -->
|
||||
<!-- <div class="mt-20px box-border w-398px border border-[#EEEEEE] rounded-10px border-solid bg-[#FFFFFF] pa-20px">
|
||||
<div class="mb-20px flex items-center text-16px text-[#333333] font-normal">
|
||||
<div class="mr-14px h-24px w-4px rounded-1px bg-[#1A65FF]"></div>
|
||||
标签列表
|
||||
</div>
|
||||
<div class="flex flex-wrap">
|
||||
<div
|
||||
v-for="item in 10"
|
||||
:key="item"
|
||||
class="mb-19px mr-26px box-border border border-[#D7D7D7] rounded-4px border-solid px-8px py-12px text-16px text-[#1A65FF] font-normal"
|
||||
># 标签名称1</div
|
||||
>
|
||||
</div>
|
||||
</div> -->
|
||||
<!-- -->
|
||||
<!-- <div class="mt-20px box-border w-398px border border-[#EEEEEE] rounded-10px border-solid bg-[#FFFFFF] pa-20px">
|
||||
<div class="mb-20px flex items-center text-16px text-[#333333] font-normal">
|
||||
<div class="mr-14px h-24px w-4px rounded-1px bg-[#1A65FF]"></div>
|
||||
猜你喜欢
|
||||
</div>
|
||||
<div
|
||||
v-for="item in 4"
|
||||
:key="item"
|
||||
class="mt-16px flex items-center border-b-1px border-b-[#eee] border-b-solid pb-16px text-16px text-[#333333] font-normal"
|
||||
>
|
||||
<img src="~/assets/images/aucad.png" alt="" srcset="" class="h-68px w-110px" />
|
||||
<div class="ml-20px text-16px text-[#333333] font-normal">Stable Diffusion 商业变现与 绘画大模型多场景实战</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -113,14 +67,14 @@
|
||||
<script setup lang="ts">
|
||||
import KlNavTab from '~/components/kl-nav-tab/index.vue'
|
||||
import { page } from '~/api/toolbox/index.js'
|
||||
import type { TpageReq, TpageRes } from '~/api/toolbox/types'
|
||||
import { reactive, ref } from 'vue'
|
||||
import { reactive, ref, watch } from 'vue'
|
||||
import KlSearch from '~/pages/toolbox/components/search.vue'
|
||||
import { getRelationRecommend } from '~/api/drawe-detail/index'
|
||||
import type { ProjectDrawPageRespVO } from '~/api/drawe-detail/types'
|
||||
import { parent } from '~/api/upnew/index'
|
||||
import emptyImg from '~/assets/images/empty.png'
|
||||
import dayjs from 'dayjs'
|
||||
import KlWallpaperCategory from '~/components/toolbox-components/kl-wallpaper-category.vue'
|
||||
|
||||
const cascaderProps = { multiple: false, label: 'name', value: 'id', emitPath: false }
|
||||
|
||||
@ -128,19 +82,44 @@
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
title: '',
|
||||
categoryId: undefined,
|
||||
sourceType: 0,
|
||||
categoryId: '-1',
|
||||
sourceType: -1,
|
||||
})
|
||||
|
||||
// const pageRes = ref<TpageRes>({
|
||||
// list: [],
|
||||
// total: 0,
|
||||
// })
|
||||
const tabBar = ref([
|
||||
{
|
||||
label: '推荐工具',
|
||||
value: -1,
|
||||
},
|
||||
{
|
||||
label: '原创开发',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
label: '转载分享',
|
||||
value: 1,
|
||||
},
|
||||
])
|
||||
|
||||
const recommedComputed = computed(() => {
|
||||
if (pageReq.sourceType === -1) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
const loading = ref(false)
|
||||
const { data: pageRes, refresh: getPage } = await useAsyncData(
|
||||
`draw-page-toobox-list`,
|
||||
async () => {
|
||||
const res = await page(pageReq)
|
||||
loading.value = true
|
||||
const res = await page({
|
||||
...pageReq,
|
||||
recommend: recommedComputed,
|
||||
sourceType: pageReq.sourceType === -1 ? undefined : pageReq.sourceType,
|
||||
categoryId: pageReq.categoryId === '-1' ? undefined : pageReq.categoryId,
|
||||
})
|
||||
loading.value = false
|
||||
if (res.code === 0) {
|
||||
return res.data
|
||||
}
|
||||
@ -154,22 +133,6 @@
|
||||
}
|
||||
)
|
||||
|
||||
const loading = ref(false)
|
||||
// const getPage = () => {
|
||||
// loading.value = true
|
||||
// page(pageReq)
|
||||
// .then((res) => {
|
||||
// if (res.code === 0) {
|
||||
// pageRes.value = res.data
|
||||
// }
|
||||
// })
|
||||
// .finally(() => {
|
||||
// loading.value = false
|
||||
// })
|
||||
// }
|
||||
|
||||
// getPage()
|
||||
|
||||
const handleCurrentChange = (page: number) => {
|
||||
pageReq.pageNo = page
|
||||
getPage()
|
||||
@ -205,4 +168,8 @@
|
||||
})
|
||||
return res.data
|
||||
})
|
||||
|
||||
watch([() => pageReq.sourceType, () => pageReq.categoryId], (val) => {
|
||||
getPage()
|
||||
})
|
||||
</script>
|
||||
|
||||
11
plugins/error-handler.ts
Normal file
11
plugins/error-handler.ts
Normal file
@ -0,0 +1,11 @@
|
||||
export default defineNuxtPlugin((nuxtApp) => {
|
||||
nuxtApp.vueApp.config.errorHandler = (error, instance, info) => {
|
||||
// 处理错误,例如发送报告到服务
|
||||
console.log(error)
|
||||
}
|
||||
|
||||
// 也可以这样做
|
||||
// nuxtApp.hook('vue:error', (error, instance, info) => {
|
||||
// // 处理错误,例如发送报告到服务
|
||||
// })
|
||||
})
|
||||
@ -99,6 +99,39 @@ export default defineStore('useUserStore', {
|
||||
console.error('getToken error:', error)
|
||||
}
|
||||
},
|
||||
async getTokenV2(row: any) {
|
||||
const app = useNuxtApp()
|
||||
try {
|
||||
const res = await socialLoginByCode({
|
||||
openId: row.openId,
|
||||
sceneStr: row.sceneStr,
|
||||
type: 32
|
||||
})
|
||||
|
||||
const { code, data } = res
|
||||
if (code === 0) {
|
||||
// 打开登录界面
|
||||
if (!data.accessToken) {
|
||||
ElMessage.error('因你未绑定手机号,请先绑定手机号')
|
||||
app.$openLogin('verify', row.code, row.type, row.state)
|
||||
} else {
|
||||
refreshToken.setToken(data.accessToken, data.refreshToken)
|
||||
refreshToken.setUserId(data.userId.toString())
|
||||
// refreshToken.setUserName(loginForm.mobile)
|
||||
this.setToken(data.accessToken)
|
||||
this.setUserId(data.userId.toString())
|
||||
// userStore.setUserName(loginForm.mobile)
|
||||
this.setRefreshToken(data.refreshToken)
|
||||
// 获取信息
|
||||
await this.getUserInfo()
|
||||
}
|
||||
} else {
|
||||
console.error('获取token失败:', res.msg)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('getToken error:', error)
|
||||
}
|
||||
},
|
||||
},
|
||||
persist: import.meta.client && {
|
||||
key: 'tuxixi-store',
|
||||
|
||||
Reference in New Issue
Block a user