Compare commits
151 Commits
4fb57c13c7
...
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 | |||
| 7f7664e68f | |||
| 6f58ba2389 | |||
| 33430e0888 | |||
| 5b498724c4 | |||
| aef8799652 | |||
| bf189f7f5b | |||
| 06b60a4ff9 | |||
| c11116d9a9 | |||
| 48d4ede98e | |||
| fd31274a21 | |||
| ec5cddae61 | |||
| e361ff9c79 | |||
| c93cfeb266 | |||
| 4b36bc2e06 | |||
| ce3aab1c76 | |||
| 0efb671bff | |||
| c0d41b4d8d | |||
| 394df57af1 | |||
| ab57b6c9b2 | |||
| 87ce756f6b | |||
| 9d2863d6d3 | |||
| 8677405266 | |||
| a8b55412c6 | |||
| cc2f0d5eeb | |||
| 9c62a6a198 | |||
| b1174fc1e3 | |||
| e6c99fbbca | |||
| 239a1272b2 | |||
| 0d4c625b10 | |||
| dc824592ce | |||
| d096ebb83c | |||
| a0a44b4551 | |||
| cef6c8c341 | |||
| 9d4dda04c9 | |||
| 8754d3a333 | |||
| 8d9bc93955 | |||
| 1e292102d1 | |||
| 9417601ab1 | |||
| 2901b24f43 | |||
| f3fb25349b | |||
| ad61430545 | |||
| 164690bcce | |||
| 2ac31bc1a3 | |||
| 41ff1b8f44 | |||
| 9ac4fa6e5d | |||
| 0bc2bdb9bb | |||
| 4db377161c | |||
| a60b28aa22 | |||
| fec929bf06 | |||
| b0b50ed960 | |||
| 78939951d9 | |||
| 02bc9c00b0 | |||
| 823e3d9f99 | |||
| a1735a5e94 | |||
| 7839fa565e | |||
| 9054376279 | |||
| 3ae61916ca | |||
| 1a86b4cb7e | |||
| 7a33f67aed | |||
| 9f5942546d | |||
| 7c82166781 | |||
| cd58054cfa | |||
| 615ac78156 | |||
| 18ebc08645 | |||
| d006b3e5af | |||
| b7d6b37e87 | |||
| 24d2b82221 | |||
| d24ece1724 | |||
| 0e8fb5c838 | |||
| c8d47fd959 | |||
| bdad6d4406 | |||
| 3d8ae8816d | |||
| c01f51a488 | |||
| 5073c33e61 | |||
| 4dcd59f1d4 | |||
| 1a27904f23 | |||
| 85c49890d1 | |||
| 272c380c6e | |||
| 5092efdaeb | |||
| df3873c6eb | |||
| addef04ff0 | |||
| b1d2378cec | |||
| 7f2edb91e4 | |||
| 694a032d0a | |||
| a96dbb67fe | |||
| d26970fb3d | |||
| 9222d47b37 | |||
| acb7ccaf46 | |||
| e1c1fefa20 | |||
| 21780580b8 | |||
| e0507f3bd1 | |||
| fa971cff5b | |||
| a900399dd0 | |||
| 8761a91f13 | |||
| f4312f5f0c | |||
| 2c2e6f600b | |||
| cb56f9b7ba | |||
| be82375202 | |||
| a0f1ec758e | |||
| 7ecff344de | |||
| 7a8f096513 | |||
| 80a48e1e71 | |||
| f6a1dc3513 | |||
| cb89a861c1 | |||
| 18d93d3a2a | |||
| 31f8d6d23d | |||
| 316d82b3ad | |||
| 8e26ae9cde | |||
| 22539f3839 | |||
| 469900d3ac | |||
| 9675261481 | |||
| 3153a35daf | |||
| 966c5feb5e | |||
| f7784e8305 | |||
| 048dd1fe65 | |||
| dbc15f5f52 | |||
| e30abf7f83 | |||
| 7a91eddbb4 | |||
| e036c88535 |
@ -49,7 +49,7 @@ export const getChannelPosts = (params: { id: number }) => {
|
|||||||
* @return {Promise}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
export const postsDelete = (params: { id: number }) => {
|
export const postsDelete = (params: { id: number }) => {
|
||||||
return useDollarFetchRequest.del<IResponse<boolean>>('/prod-api/app-api/business/posts/delete', { params })
|
return useDollarFetchRequest.del<IResponse<boolean>>('/prod-api/app-api/business/posts/delete?id=' + params.id, {})
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 获取帖子详情
|
* 获取帖子详情
|
||||||
@ -64,7 +64,7 @@ export const getChannelDetail = (params: { id: string }) => {
|
|||||||
* @return {Promise}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
export const postscommentpage = (params: { postsId: string; pageNo: number; pageSize: number }) => {
|
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 })
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 创建帖子评论
|
* 创建帖子评论
|
||||||
@ -147,5 +147,5 @@ export const deleteChannelFollow = (params: { channelId: string }) => {
|
|||||||
* 根据群组ID获取群组成员
|
* 根据群组ID获取群组成员
|
||||||
*/
|
*/
|
||||||
export const getGroupMembers = (params: { channelId: string }) => {
|
export const getGroupMembers = (params: { channelId: string }) => {
|
||||||
return useFetchRequest.get<IResponse<MemberUserRespDTO[]>>(`/prod-api/app-api/mqtt/session/users/${params.channelId}`)
|
return useDollarFetchRequest.get<IResponse<MemberUserRespDTO[]>>(`/prod-api/app-api/mqtt/session/users/${params.channelId}`)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,22 +7,22 @@ import type { ProjectRespVO, PageResultProjectCommentResVO, ProjectDrawPageRespV
|
|||||||
* @return {Promise}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
export const getDetail = (params: { id?: number | string }) => {
|
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}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
export const getCommentList = (params: { relationId?: number | string; pageNum?: number; pageSize?: number }) => {
|
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 useDollarFetchRequest.get<IResponse<PageResultProjectCommentResVO>>('/prod-api/app-api/business/app/project-comment/page', { query: params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发表评论
|
* 发表评论
|
||||||
* @return {Promise}
|
* @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)
|
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}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
export const getRelationRecommend = (params: { type?: number | string; projectType?: number | string }) => {
|
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}
|
* @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)
|
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 })
|
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)
|
return useDollarFetchRequest.post<IResponse<boolean>>('/prod-api/app-api/business/project-member-favorites/create', params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -35,6 +35,7 @@ export interface ProjectRespVO {
|
|||||||
projectTypeName: string
|
projectTypeName: string
|
||||||
favoriteId?: string
|
favoriteId?: string
|
||||||
relationDraws: RelationDraws[]
|
relationDraws: RelationDraws[]
|
||||||
|
no?: string
|
||||||
filesInfo: {
|
filesInfo: {
|
||||||
fileSize: string
|
fileSize: string
|
||||||
count: number
|
count: number
|
||||||
@ -136,6 +137,7 @@ export interface UserExtendSimpleRespDTO {
|
|||||||
files: any[]
|
files: any[]
|
||||||
fansCount: number
|
fansCount: number
|
||||||
projectCount: number
|
projectCount: number
|
||||||
|
postsNum?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProjectDrawMemberRespVO {
|
export interface ProjectDrawMemberRespVO {
|
||||||
|
|||||||
@ -7,6 +7,8 @@ import type {
|
|||||||
ProjectDrawStatisticAppRespVO,
|
ProjectDrawStatisticAppRespVO,
|
||||||
ProjectTrendingScoreUserInfoVO,
|
ProjectTrendingScoreUserInfoVO,
|
||||||
PageResultIndexSettingRespVO,
|
PageResultIndexSettingRespVO,
|
||||||
|
TdkSettingsRespVO,
|
||||||
|
TdkSettingsDO,
|
||||||
} from './type'
|
} from './type'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -86,5 +88,26 @@ export const tab2 = () => {
|
|||||||
* 获取具有上下级关系的当前的名称
|
* 获取具有上下级关系的当前的名称
|
||||||
*/
|
*/
|
||||||
export const getDictTree = (params: { type: number, id: number}) => {
|
export const getDictTree = (params: { type: number, id: number}) => {
|
||||||
return useDollarFetchRequest.get<IResponse<ProjectDictNodeVO[]>>('/prod-api/app-api/business/dict/level-by-id', { query: params })
|
return useDollarFetchRequest.get<IResponse<ProjectDictNodeVO[]>>('/prod-api/app-api/business/app/dict/path-by-id', { query: params })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得网站 TDK设置
|
||||||
|
*/
|
||||||
|
export const getTDK = () => {
|
||||||
|
return useFetchRequest.get<IResponse<TdkSettingsRespVO>>('/prod-api/app-api/business/tdk-settings/get-index', {})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得网站 TDK栏目列表
|
||||||
|
*/
|
||||||
|
export const getTDKList = () => {
|
||||||
|
return useFetchRequest.get<IResponse<TdkSettingsDO[]>>('/prod-api/app-api/business/tdk-settings/list-menu', {})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通知列表
|
||||||
|
*/
|
||||||
|
export const getNoticeList = () => {
|
||||||
|
return useDollarFetchRequest.get<IResponse<any>>('/prod-api/app-api/system/index-setting/notice-list', {})
|
||||||
|
}
|
||||||
@ -105,3 +105,25 @@ export interface PageResultIndexSettingRespVO {
|
|||||||
status: number
|
status: number
|
||||||
createTime: string
|
createTime: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TdkSettingsRespVO {
|
||||||
|
title: string
|
||||||
|
describeText: string
|
||||||
|
keyword: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TdkSettingsDO {
|
||||||
|
createTime?: string
|
||||||
|
updateTime?: string
|
||||||
|
creator?: string
|
||||||
|
updater?: string
|
||||||
|
deleted?: boolean
|
||||||
|
id?: number
|
||||||
|
title?: string
|
||||||
|
icon?: string
|
||||||
|
type?: number
|
||||||
|
path: string
|
||||||
|
describeText?: string
|
||||||
|
keyword?: string
|
||||||
|
remark: string
|
||||||
|
}
|
||||||
|
|||||||
@ -27,8 +27,18 @@ export const loginByMobile = (params: { mobile: string; code: string; socialCode
|
|||||||
/**
|
/**
|
||||||
* 发送邮箱验证码
|
* 发送邮箱验证码
|
||||||
*/
|
*/
|
||||||
export const sendEmailCode = (params: { email: string }) => {
|
export const sendEmailCode = (data: { email: string }) => {
|
||||||
return useDollarFetchRequest.post<IResponse<any>>('/prod-api/app-api/member/auth/send-email-code', params)
|
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, */*',
|
||||||
|
'Access-Control-Allow-Origin-Type': '*',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,3 +54,10 @@ export const loginByEmail = (params: { email: string; code: string }) => {
|
|||||||
export const resetPassword = (params: { password: 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)
|
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 })
|
||||||
|
}
|
||||||
|
|||||||
@ -36,26 +36,26 @@ export const createOrder = (params: { spuId: number }) => {
|
|||||||
* 获得钱包充值套餐列表
|
* 获得钱包充值套餐列表
|
||||||
*/
|
*/
|
||||||
export const listWalletRechargePackage = () => {
|
export const listWalletRechargePackage = () => {
|
||||||
return useDollarFetchRequest.get<IResponse<AppPayWalletPackageRespVO[]>>('/prod-api/app-api/pay/wallet-recharge-package/list', {})
|
return useDollarFetchRequest.get<IResponse<AppPayWalletPackageRespVO[]>>('/prod-api/app-api/pay/wallet-recharge-package/list', {})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取支付状态
|
* 获取支付状态
|
||||||
*/
|
*/
|
||||||
export const getPayStatus = (params: { id: number }) => {
|
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 })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过code获取token
|
* 通过code获取token
|
||||||
*/
|
*/
|
||||||
export const getTokenByCode = (params: { type: number; code: string; state: string }) => {
|
export const getTokenByCode = (params: { type: number; code: string; state: string }) => {
|
||||||
return useDollarFetchRequest.post<IResponse<string>>('/prod-api/app-api/member/auth/token-by-code', params)
|
return useDollarFetchRequest.post<IResponse<string>>('/prod-api/app-api/member/auth/token-by-code', params)
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 社交快捷登录,使用 code 授权码
|
* 社交快捷登录,使用 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<
|
return useDollarFetchRequest.post<
|
||||||
IResponse<{
|
IResponse<{
|
||||||
accessToken: string
|
accessToken: string
|
||||||
@ -71,5 +71,5 @@ export const socialLoginByCode = (params: { type: number; code: string; state: s
|
|||||||
* 获得钱包充值记录分页
|
* 获得钱包充值记录分页
|
||||||
*/
|
*/
|
||||||
export const getWalletRechargeRecordPage = (params: { pageNo: number; pageSize: number }) => {
|
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 })
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,7 +43,7 @@ export const updateUserExtend = (params: UserExtendSaveReqVO) => {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const getUserAuthInfo = () => {
|
export const getUserAuthInfo = () => {
|
||||||
return useFetchRequest.get<IResponse<UserAuthInfoRespVO>>('/prod-api/app-api/member/user-auth-info/get', {})
|
return useDollarFetchRequest.get<IResponse<UserAuthInfoRespVO>>('/prod-api/app-api/member/user-auth-info/get', {})
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 创建用户信息
|
* 创建用户信息
|
||||||
@ -66,13 +66,13 @@ export const updateUserAuthInfo = (params: UserAuthInfoRespVO) => {
|
|||||||
* 获得内容信息分页
|
* 获得内容信息分页
|
||||||
*/
|
*/
|
||||||
export const getContentPage = (params: { type: number }) => {
|
export const getContentPage = (params: { type: number }) => {
|
||||||
return useDollarFetchRequest.get<IResponse<PageResultProjectHistoryResVO>>('/prod-api/app-api/business/project-history/page', {query:params})
|
return useDollarFetchRequest.get<IResponse<PageResultProjectHistoryResVO>>('/prod-api/app-api/business/project-history/page', { query: params })
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 获得用户项目工具箱下载分页
|
* 获得用户项目工具箱下载分页
|
||||||
*/
|
*/
|
||||||
export const getUserToolBoxPage = (params: { pageNum: number; pageSize: number; type?: number }) => {
|
export const getUserToolBoxPage = (params: { pageNum: number; pageSize: number; type?: number }) => {
|
||||||
return useDollarFetchRequest.get<IResponse<PageResultProjectHistoryResVO>>('/prod-api/app-api/business/project-member-file/page', {query:params})
|
return useDollarFetchRequest.get<IResponse<PageResultProjectHistoryResVO>>('/prod-api/app-api/business/project-member-file/page', { query: params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,20 +92,20 @@ export const signIn = () => {
|
|||||||
* 获得用户积分记录分页
|
* 获得用户积分记录分页
|
||||||
*/
|
*/
|
||||||
export const getUserPointPage = (params: { pageNo: number; pageSize: number }) => {
|
export const getUserPointPage = (params: { pageNo: number; pageSize: number }) => {
|
||||||
return useDollarFetchRequest.get<IResponse<PageResultMemberPointRecordRespVO>>('/prod-api/app-api/member/point/record/page', {query:params})
|
return useDollarFetchRequest.get<IResponse<PageResultMemberPointRecordRespVO>>('/prod-api/app-api/member/point/record/page', { query: params })
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 近期收益和近期活跃
|
* 近期收益和近期活跃
|
||||||
*/
|
*/
|
||||||
export const getRecentIncomeAndActive = (params: { type: number; limit: number }) => {
|
export const getRecentIncomeAndActive = (params: { type: number; limit: number }) => {
|
||||||
return useDollarFetchRequest.get<IResponse<UserStatisticsLineRespVO>>('/prod-api/app-api/member/statistics/line', {query:params})
|
return useDollarFetchRequest.get<IResponse<UserStatisticsLineRespVO>>('/prod-api/app-api/member/statistics/line', { query: params })
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
资源下载分布
|
资源下载分布
|
||||||
*/
|
*/
|
||||||
export const getResourceDistribution = (params: { type: number; limit: number }) => {
|
export const getResourceDistribution = (params: { type: number; limit: number }) => {
|
||||||
return useDollarFetchRequest.get<IResponse<UserStatisticsBarRespVO>>('/prod-api/app-api/member/statistics/bar', {query:params})
|
return useDollarFetchRequest.get<IResponse<UserStatisticsBarRespVO>>('/prod-api/app-api/member/statistics/bar', { query: params })
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 我的数据统计 包括我的金币 我的关注 我的发布等等
|
* 我的数据统计 包括我的金币 我的关注 我的发布等等
|
||||||
@ -118,28 +118,30 @@ export const getUserStatistics = () => {
|
|||||||
* 获得项目订单用户收藏信息分页
|
* 获得项目订单用户收藏信息分页
|
||||||
*/
|
*/
|
||||||
export const getUserFavoritePage = (params: { pageNo: number; pageSize: number; userId: any; type: number }) => {
|
export const getUserFavoritePage = (params: { pageNo: number; pageSize: number; userId: any; type: number }) => {
|
||||||
return useDollarFetchRequest.get<IResponse<PageResultProjectMemberFavoritesRespVO>>('/prod-api/app-api/business/project-member-favorites/page', {query:params})
|
return useDollarFetchRequest.get<IResponse<PageResultProjectMemberFavoritesRespVO>>('/prod-api/app-api/business/project-member-favorites/page', {
|
||||||
|
query: params,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* 自己发布的-内容信息分页
|
* 自己发布的-内容信息分页
|
||||||
*/
|
*/
|
||||||
export const getOwnContentPage = (params: { pageNo: number; pageSize: number; type: number }) => {
|
export const getOwnContentPage = (params: { pageNo: number; pageSize: number; type: number }) => {
|
||||||
return useDollarFetchRequest.get<IResponse<PageResultProjectHistoryResVO>>('/prod-api/app-api/business/app/project-draw/my-page', {query:params})
|
return useDollarFetchRequest.get<IResponse<PageResultProjectHistoryResVO>>('/prod-api/app-api/business/app/project-draw/my-page', { query: params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 下架
|
* 下架
|
||||||
*/
|
*/
|
||||||
export const offShelf = (params: { id: number }) => {
|
export const offShelf = (params: { id: number }) => {
|
||||||
return useDollarFetchRequest.put<IResponse<boolean>>('/prod-api/app-api/business/app/project-draw/down', params)
|
return useDollarFetchRequest.put<IResponse<boolean>>('/prod-api/app-api/business/app/project-draw/down?id=' + params.id, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除资源
|
* 删除资源
|
||||||
*/
|
*/
|
||||||
export const deleteResource = (params: { id: number }) => {
|
export const deleteResource = (params: { id: number }) => {
|
||||||
return useDollarFetchRequest.del<IResponse<boolean>>('/prod-api/app-api/business/app/project-draw/delete', params)
|
return useDollarFetchRequest.del<IResponse<boolean>>('/prod-api/app-api/business/app/project-draw/delete?id=' + params.id, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -148,3 +150,49 @@ export const deleteResource = (params: { id: number }) => {
|
|||||||
export const getUserExtend = () => {
|
export const getUserExtend = () => {
|
||||||
return useFetchRequest.get<IResponse<UserExtendRespVO>>('/prod-api/app-api/member/user-extend/get', {})
|
return useFetchRequest.get<IResponse<UserExtendRespVO>>('/prod-api/app-api/member/user-extend/get', {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消社交绑定
|
||||||
|
*/
|
||||||
|
export const cancelSocialBind = (params: { type: number; openid: string }) => {
|
||||||
|
return useDollarFetchRequest.post<IResponse<boolean>>('/prod-api/app-api/member/social-user/unbind', params)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户注销账号
|
||||||
|
*/
|
||||||
|
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,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@ -46,6 +46,8 @@ export interface UserExtendRespVO {
|
|||||||
description: string
|
description: string
|
||||||
authStatus: number
|
authStatus: number
|
||||||
createTime: string
|
createTime: string
|
||||||
|
wxOpenId: string
|
||||||
|
qqOpenId: string
|
||||||
files: {
|
files: {
|
||||||
id: number
|
id: number
|
||||||
memberId: number
|
memberId: number
|
||||||
@ -153,6 +155,7 @@ export interface UserStatisticsCountRespVO {
|
|||||||
currencyCount: number
|
currencyCount: number
|
||||||
previewCount: number
|
previewCount: number
|
||||||
revenueCount: number
|
revenueCount: number
|
||||||
|
revenueBalance: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PageResultProjectMemberFavoritesRespVO {
|
export interface PageResultProjectMemberFavoritesRespVO {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import * as useDollarFetchRequest from '~/composables/useDollarFetchRequest'
|
import * as useDollarFetchRequest from '~/composables/useDollarFetchRequest'
|
||||||
import * as useFetchRequest from '~/composables/useFetchRequest'
|
import * as useFetchRequest from '~/composables/useFetchRequest'
|
||||||
import type { TcreateReq, TpageReq, TpageRes } from './types'
|
import type { TcreateReq, TpageReq, TpageRes, ProjectResourceRespVO } from './types'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新建工具箱
|
* 新建工具箱
|
||||||
@ -8,12 +8,23 @@ import type { TcreateReq, TpageReq, TpageRes } from './types'
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const create = (params: TcreateReq) => {
|
export const create = (params: TcreateReq) => {
|
||||||
return useDollarFetchRequest.post<IResponse<number>>('/prod-api/app-api/business/app/project-resource/create', params)
|
return useDollarFetchRequest.post<IResponse<number>>('/prod-api/app-api/business/resource/create', params)
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* 获得内容信息分页
|
* 获得内容信息分页
|
||||||
*/
|
*/
|
||||||
export const page = (params: TpageReq) => {
|
export const page = (params: any) => {
|
||||||
return useFetchRequest.get<IResponse<TpageRes>>('/prod-api/app-api/business/app/project-resource/page', {query:params})
|
return useFetchRequest.get<IResponse<TpageRes>>('/prod-api/app-api/business/resource/page', {
|
||||||
|
query: params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得工具箱
|
||||||
|
*/
|
||||||
|
export const get = (params: { id: string }) => {
|
||||||
|
return useFetchRequest.get<IResponse<ProjectResourceRespVO>>('/prod-api/app-api/business/resource/get', {
|
||||||
|
query: params,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,9 @@ export interface TcreateReq {
|
|||||||
createAddress?: string
|
createAddress?: string
|
||||||
createIp?: string
|
createIp?: string
|
||||||
projectType: number[]
|
projectType: number[]
|
||||||
|
categoryId?: number
|
||||||
|
sourceType?: number
|
||||||
|
categoryName?: string
|
||||||
files: {
|
files: {
|
||||||
id: number
|
id: number
|
||||||
title: string
|
title: string
|
||||||
@ -59,3 +62,57 @@ export interface TpageItem {
|
|||||||
commentsPoint: number
|
commentsPoint: number
|
||||||
ownedUserId: string
|
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
|
||||||
|
}
|
||||||
|
|||||||
@ -16,7 +16,7 @@ export const create = (params: TcreateReq) => {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const parent = (params: { type: string | number; parentId: number | string }) => {
|
export const parent = (params: { type: string | number; parentId: number | string }) => {
|
||||||
return useFetchRequest.get<IResponse<parentRes[]>>('/prod-api/app-api/business/app/dict/parent', { query: params })
|
return useDollarFetchRequest.get<IResponse<parentRes[]>>('/prod-api/app-api/business/app/dict/parent', { query: params })
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 获取具有上下级的字典信息
|
* 获取具有上下级的字典信息
|
||||||
@ -32,7 +32,7 @@ export const parentV2 = (params: { type: string | number; parentId: number | str
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const indexTabs = () => {
|
export const indexTabs = () => {
|
||||||
return useFetchRequest.get<IResponse<parentRes[]>>('/prod-api/app-api/business/project/index/index-tab3')
|
return useDollarFetchRequest.get<IResponse<parentRes[]>>('/prod-api/app-api/business/project/index/index-tab3')
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 模糊查询获取标签内容
|
* 模糊查询获取标签内容
|
||||||
@ -40,7 +40,7 @@ export const indexTabs = () => {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const keywords = (params: { type: string | number; keywords: string }) => {
|
export const keywords = (params: { type: string | number; keywords: string }) => {
|
||||||
return useFetchRequest.get<IResponse<boolean>>('/prod-api/app-api/business/app/dict/label-keywords', {query:params})
|
return useFetchRequest.get<IResponse<boolean>>('/prod-api/app-api/business/app/dict/label-keywords', { query: params })
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 获取格式类型字典信息
|
* 获取格式类型字典信息
|
||||||
@ -73,3 +73,24 @@ export const recommendTop = (params: recommendTopReq) => {
|
|||||||
export const homeLabel = () => {
|
export const homeLabel = () => {
|
||||||
return useFetchRequest.get<IResponse<ProjectDictNodeVO[]>>('/prod-api/app-api/business/app/dict/index-tab')
|
return useFetchRequest.get<IResponse<ProjectDictNodeVO[]>>('/prod-api/app-api/business/app/dict/index-tab')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取客服微信
|
||||||
|
*/
|
||||||
|
export const getWechat = () => {
|
||||||
|
return useDollarFetchRequest.get<IResponse<string>>('/prod-api/app-api/system/index-setting/kefu-wechat')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看图纸
|
||||||
|
*/
|
||||||
|
export const view = (params: { id: string | number; projectId: string | number }) => {
|
||||||
|
return useDollarFetchRequest.get<IResponse<TcreateReq>>('/prod-api/app-api/business/app/project-draw/get', { query: params })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑图纸
|
||||||
|
*/
|
||||||
|
export const edit = (data: TcreateReq) => {
|
||||||
|
return useDollarFetchRequest.put<IResponse<boolean>>('/prod-api/app-api/business/app/project/update', data)
|
||||||
|
}
|
||||||
|
|||||||
@ -10,9 +10,9 @@ export interface FileItem {
|
|||||||
|
|
||||||
// 定义整个 JSON 对象的类型
|
// 定义整个 JSON 对象的类型
|
||||||
export interface TcreateReq {
|
export interface TcreateReq {
|
||||||
activeName: string
|
activeName: string | number
|
||||||
id: number | string
|
id: number | string
|
||||||
type: any[]
|
type: number
|
||||||
isDomestic: number | string
|
isDomestic: number | string
|
||||||
province: string // 省份编码
|
province: string // 省份编码
|
||||||
city: string // 城市编码
|
city: string // 城市编码
|
||||||
@ -61,6 +61,7 @@ export interface pageReq {
|
|||||||
createAddress?: string
|
createAddress?: string
|
||||||
createIp?: string
|
createIp?: string
|
||||||
projectType?: any
|
projectType?: any
|
||||||
|
recommend: boolean // 是否推荐
|
||||||
}
|
}
|
||||||
export interface pageRes {
|
export interface pageRes {
|
||||||
list: {
|
list: {
|
||||||
@ -79,6 +80,7 @@ export interface pageRes {
|
|||||||
previewPoint?: number
|
previewPoint?: number
|
||||||
commentsPoint?: number
|
commentsPoint?: number
|
||||||
hotPoint?: number
|
hotPoint?: number
|
||||||
|
source?: number
|
||||||
}[]
|
}[]
|
||||||
total: number
|
total: number
|
||||||
}
|
}
|
||||||
|
|||||||
25
app.vue
@ -7,4 +7,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts"></script>
|
<script setup lang="ts">
|
||||||
|
import refreshToken from '~/utils/RefreshToken'
|
||||||
|
import useUserStore from '~/stores/user'
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (!userStore.mqttClient) {
|
||||||
|
// 判断建立连接没 刷新会走这儿
|
||||||
|
userStore.connectMqtt()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 浏览器打开新的tab页,防止数据不一致
|
||||||
|
document.addEventListener('visibilitychange', () => {
|
||||||
|
if (userStore.token !== refreshToken.getToken().token) {
|
||||||
|
location.reload()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
// 断开连接
|
||||||
|
userStore.mqttClient?.disconnect()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|||||||
BIN
assets/images/activity1.png
Normal file
|
After Width: | Height: | Size: 92 KiB |
BIN
assets/images/activity2.png
Normal file
|
After Width: | Height: | Size: 109 KiB |
BIN
assets/images/avater2 copy.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
assets/images/banner copy.png
Normal file
|
After Width: | Height: | Size: 434 KiB |
BIN
assets/images/bg-yy.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/images/crown.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
assets/images/faxian.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
assets/images/home-l (1).png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
assets/images/home-l (2).png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/images/home-l (3).png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/images/info copy.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
assets/images/info.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
assets/images/my_attention.png
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
BIN
assets/images/my_collect.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
assets/images/my_download.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
assets/images/my_release.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
assets/images/pingdao.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
assets/images/shouye.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
assets/images/talent-detail-bg.png
Normal file
|
After Width: | Height: | Size: 324 KiB |
BIN
assets/images/technicalCertificates.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
assets/images/tuzhi (1).png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
assets/images/tuzhi (2).png
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
assets/images/tuzhi (3).png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
assets/images/tuzhi (4).png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
assets/images/tuzhi (5).png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
BIN
assets/images/tuzhi (6).png
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
BIN
assets/images/wode.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
assets/images/x.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
assets/images/yuan.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
assets/images/zhuan.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
@ -1,6 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mt-[30px] w-[100%]">
|
<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 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">
|
<div class="flex items-start">
|
||||||
<el-avatar :src="item.creatorInfo.avatar" alt="" srcset="" class="h-[50px] w-[49px] rounded-full" />
|
<el-avatar :src="item.creatorInfo.avatar" alt="" srcset="" class="h-[50px] w-[49px] rounded-full" />
|
||||||
@ -9,7 +11,7 @@
|
|||||||
<div class="relative top-[4px] text-[14px]!">{{ item.creatorInfo.nickName }}</div>
|
<div class="relative top-[4px] text-[14px]!">{{ item.creatorInfo.nickName }}</div>
|
||||||
<div class="text-[12px] text-[#999999] font-normal">发表时间:{{ dayjs(item.creatorInfo.createTime).format('YYYY-MM-DD HH:mm:ss') }}</div>
|
<div class="text-[12px] text-[#999999] font-normal">发表时间:{{ dayjs(item.creatorInfo.createTime).format('YYYY-MM-DD HH:mm:ss') }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-[10px] box-border rd-[4px] bg-[#f8f8f8] px-[18px] py-[10px] text-[14px] text-[#999999] font-normal">{{ item.content }}</div>
|
<div class="mt-[10px] box-border rd-[4px] bg-[#f8f8f8] px-[12px] py-[10px] text-[13px] text-[#999999] font-normal">{{ item.content }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -44,7 +46,7 @@
|
|||||||
},
|
},
|
||||||
projectId: {
|
projectId: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true,
|
required: false,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -66,7 +68,12 @@
|
|||||||
|
|
||||||
// 获取评论列表
|
// 获取评论列表
|
||||||
const handleGetCommentList = async () => {
|
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) {
|
if (res.code === 0) {
|
||||||
result.value.list = res.data.list
|
result.value.list = res.data.list
|
||||||
result.value.total = res.data.total
|
result.value.total = res.data.total
|
||||||
@ -75,7 +82,7 @@
|
|||||||
|
|
||||||
// 发表评论
|
// 发表评论
|
||||||
const handleCreateComment = async () => {
|
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) {
|
if (res.code === 0) {
|
||||||
commentContent.value = ''
|
commentContent.value = ''
|
||||||
query.value.pageNo = 1
|
query.value.pageNo = 1
|
||||||
@ -87,8 +94,9 @@
|
|||||||
() => props.relationId,
|
() => props.relationId,
|
||||||
() => {
|
() => {
|
||||||
handleGetCommentList()
|
handleGetCommentList()
|
||||||
},{
|
},
|
||||||
immediate: true
|
{
|
||||||
|
immediate: true,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="relative mt-[34px] w-[100%]">
|
<div class="relative mt-[34px] w-[100%]">
|
||||||
<KlTabBar v-model="query.source" :data="tabBar" />
|
<KlTabBar v-model="query.source" :data="tabBar" />
|
||||||
<div class="absolute right-[0px] top-[10px] text-[16px] text-[#999999] font-normal"
|
<div class="absolute right-[0px] top-[0px] text-[16px] text-[#999999] font-normal">
|
||||||
>共<span class="color-[#1A65FF]">{{ result?.total }}</span
|
<el-button type="warning" class="mr-4px" @click="handleUpload">上传工具</el-button>
|
||||||
|
共<span class="color-[#1A65FF]">{{ result?.total }}</span
|
||||||
>个筛选结果</div
|
>个筛选结果</div
|
||||||
>
|
>
|
||||||
<div class="content mt-[10px]">
|
<div class="content mt-[10px]">
|
||||||
@ -17,11 +18,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import KlTabBar from '~/components/kl-tab-bar/index.vue'
|
import KlTabBar from '~/components/kl-tab-bar/v3/index.vue'
|
||||||
import CardPicture from '~/components/kl-card-picture/index.vue'
|
import CardPicture from '~/components/kl-card-picture/index.vue'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import type { pageRes, pageReq } from '~/api/upnew/types'
|
import type { pageRes, pageReq } from '~/api/upnew/types'
|
||||||
import emptyImg from '~/assets/images/empty.png'
|
import emptyImg from '~/assets/images/empty.png'
|
||||||
|
import useUserStore from '~/stores/user'
|
||||||
|
|
||||||
const query = defineModel<pageReq>('modelValue', {
|
const query = defineModel<pageReq>('modelValue', {
|
||||||
required: true,
|
required: true,
|
||||||
@ -41,10 +43,18 @@
|
|||||||
value: 1,
|
value: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '最新上传',
|
label: '转载分享',
|
||||||
value: 2,
|
value: 2,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
const handleUpload = () => {
|
||||||
|
// 先判断登录
|
||||||
|
const store = useUserStore()
|
||||||
|
if (!store.token) {
|
||||||
|
return ElMessage.error('请先登录')
|
||||||
|
}
|
||||||
|
navigateTo('/upnew?drawType=1')
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@ -4,17 +4,33 @@
|
|||||||
<div class="banner-text">
|
<div class="banner-text">
|
||||||
<h1 class="title">开启 CAD 学习之旅</h1>
|
<h1 class="title">开启 CAD 学习之旅</h1>
|
||||||
<p class="subtitle">为你的创意引擎注入强劲动力,驱动设计梦想在市场中乘风破浪</p>
|
<p class="subtitle">为你的创意引擎注入强劲动力,驱动设计梦想在市场中乘风破浪</p>
|
||||||
<button class="join-button">快来加入</button>
|
<button class="join-button" @click="handleService">客服联系</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="banner-image">
|
<div class="banner-image">
|
||||||
<img src="~/assets/images/foreign_banner.png" alt="CAD工作环境" />
|
<img src="~/assets/images/foreign_banner.png" alt="CAD工作环境" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 打开客服弹窗 弄成组件 -->
|
||||||
|
<KlService v-if="dialogVisible" v-model:dialog-visible="dialogVisible"></KlService>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import useUserStore from '~/stores/user'
|
||||||
|
import KlService from '~/components/kl-quick-menu/components/kl-service.vue'
|
||||||
// 组件逻辑可以在这里添加
|
// 组件逻辑可以在这里添加
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const handleService = () => {
|
||||||
|
// 判断是否登录
|
||||||
|
const userStore = useUserStore()
|
||||||
|
if (!userStore.token) {
|
||||||
|
ElMessage.error('请先登录')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dialogVisible.value = true
|
||||||
|
// 读取未读消息
|
||||||
|
// readCount.value = false
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="relative mt-[34px] w-[100%]">
|
<div class="relative mt-[34px] w-[100%]">
|
||||||
<KlTabBar v-model="tabIndex" :data="tabBar" />
|
<KlTabBar v-model="query.source" :data="tabBar" />
|
||||||
<KlWallpaperCategory v-model="query" v-model:level="level" :type="1" />
|
<KlWallpaperCategory v-model="query" v-model:level="level" :type="1" />
|
||||||
<div class="absolute right-[0px] top-[10px] text-[16px] text-[#999999] font-normal"
|
<div class="absolute right-[0px] top-[0px] text-[16px] text-[#999999] font-normal"
|
||||||
>共<span class="color-[#1A65FF]">{{ result?.total }}</span
|
>共<span class="color-[#1A65FF]">{{ result?.total }}</span
|
||||||
>个筛选结果</div
|
>个筛选结果</div
|
||||||
>
|
>
|
||||||
@ -18,8 +18,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import KlTabBar from '~/components/kl-tab-bar/index.vue'
|
import KlTabBar from '~/components/kl-tab-bar/v3/index.vue'
|
||||||
import CardPicture from '~/components/kl-card-picture/index.vue'
|
import CardPicture from '~/components/kl-card-picture/index.vue'
|
||||||
|
import KlWallpaperCategory from '~/components/kl-wallpaper-category/index.vue'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import type { pageRes } from '~/api/upnew/types'
|
import type { pageRes } from '~/api/upnew/types'
|
||||||
|
|
||||||
@ -38,19 +39,19 @@
|
|||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const tabIndex = ref(1)
|
const tabIndex = ref(-1)
|
||||||
const tabBar = ref([
|
const tabBar = ref([
|
||||||
{
|
{
|
||||||
label: '图纸推荐',
|
label: '图纸推荐',
|
||||||
value: 1,
|
value: -1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '原创图纸',
|
label: '原创图纸',
|
||||||
value: 2,
|
value: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '最新上传',
|
label: '最新上传',
|
||||||
value: 3,
|
value: 2,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
</script>
|
</script>
|
||||||
@ -6,12 +6,17 @@
|
|||||||
<div class="box-border p-[16px]">
|
<div class="box-border p-[16px]">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<div class="title mr-[38px] text-[16px] text-[#333333] font-bold">{{ props.itemInfo.title }}</div>
|
<div class="title mr-[38px] text-[16px] text-[#333333] font-bold flex items-center" :title="props.itemInfo.title">
|
||||||
<div class="mt-[8px] text-[15px] text-[#999999] font-normal">by {{ props.itemInfo?.ownedUserIdInfo?.nickName }}</div>
|
<img v-if="props.itemInfo.source === 2" src="~/assets/images/zhuan.png" alt="" srcset="" class="mr-[2px] w-[22px] relative bottom-[-4px]" />
|
||||||
|
<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-[#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>
|
||||||
<div><img :src="props.itemInfo?.ownedUserIdInfo?.avatar" alt="" srcset="" class="h-[40px] w-[40px] rd-[50%]" /></div>
|
<div><img :src="props.itemInfo?.ownedUserIdInfo?.avatar" alt="" srcset="" class="h-[40px] w-[40px] rd-[50%]" /></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-[24px] flex items-center justify-between">
|
<div class="mt-[14px] flex items-center justify-between">
|
||||||
<div class="flex items-center justify-between text-[14px] text-[#666666] font-normal">
|
<div class="flex items-center justify-between text-[14px] text-[#666666] font-normal">
|
||||||
<div class="mr-[9px] flex items-center">
|
<div class="mr-[9px] flex items-center">
|
||||||
<img src="~/assets/images/look.png" alt="" srcset="" class="mr-[2px] h-[17px]" />
|
<img src="~/assets/images/look.png" alt="" srcset="" class="mr-[2px] h-[17px]" />
|
||||||
@ -35,6 +40,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import dayjs from 'dayjs'
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import type { pageRes } from '~/api/upnew/types'
|
import type { pageRes } from '~/api/upnew/types'
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mt-30px bg-[#14213d] px-[40px] pb-[20px] pt-[50px] text-white lg:px-[80px] sm:px-[60px]">
|
<div class="mt-[30px] bg-[#14213d] px-[40px] pb-[20px] pt-[50px] text-white lg:px-[80px] sm:px-[60px]">
|
||||||
<!-- 主内容区 -->
|
<!-- 主内容区 -->
|
||||||
<div class="mb-[40px] flex flex-col items-start justify-between gap-[30px] lg:flex-row">
|
<div class="mb-[40px] flex flex-col items-start justify-between gap-[30px] lg:flex-row">
|
||||||
<!-- 左侧 Logo -->
|
<!-- 左侧 Logo -->
|
||||||
<div class="mx-auto w-[200px] shrink-0 lg:mx0">
|
<div class="mx-auto w-[200px] shrink-0 lg:mx-0">
|
||||||
<img src="~/assets/images/logo5.png" class="h-auto w-full" />
|
<img src="~/assets/images/logo5.png" class="h-auto w-full" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 中间部分 -->
|
<!-- 中间部分 -->
|
||||||
<div class="grid grid-cols-2 mx-[80px] flex-1 gap-[10px] lg:grid-cols-3">
|
<div class="grid grid-cols-2 mx-[80px] flex-1 gap-[10px] lg:grid-cols-3">
|
||||||
<div v-for="(col, index) in bannerList?.slice(0, 3)" :key="index">
|
<div v-for="(col, index) in bannerList?.slice(0, 3)" :key="index">
|
||||||
<h3 v-if="handle(col)" class="ma-0px mb-[20px] pa-0px text-[16px]">{{ handle(col) }}</h3>
|
<h3 v-if="handle(col)" class="ma-[0px] mb-[20px] pa-[0px] text-[16px]">{{ handle(col) }}</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li
|
<li
|
||||||
v-for="(item, i) in handle2(col)"
|
v-for="(item, i) in handle2(col)"
|
||||||
@ -44,6 +44,8 @@
|
|||||||
<div class="border-t border-white/20 pt-[20px] text-center text-[14px] text-white/70">
|
<div class="border-t border-white/20 pt-[20px] text-center text-[14px] text-white/70">
|
||||||
Copyright 2007-2025 图夕夕网络科技(成都)有限公司
|
Copyright 2007-2025 图夕夕网络科技(成都)有限公司
|
||||||
<a href="http://beian.miit.gov.cn/" target="_blank" class="text-white/90 hover:text-blue-400!"> 蜀ICP备2025141494号-1</a>
|
<a href="http://beian.miit.gov.cn/" target="_blank" class="text-white/90 hover:text-blue-400!"> 蜀ICP备2025141494号-1</a>
|
||||||
|
<img src="~/assets/images/x.png" class="w-[20px] h-[20px] relative top-[2px]" />
|
||||||
|
<a href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=51010702043645" rel="noreferrer" target="_blank">川公网安备51010702043645号</a >
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-image-viewer v-if="showViewer" :url-list="previewImgList" :url-index="0" @close="showViewer = false"></el-image-viewer>
|
<el-image-viewer v-if="showViewer" :url-list="previewImgList" :url-index="0" @close="showViewer = false"></el-image-viewer>
|
||||||
|
|||||||
@ -8,13 +8,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="item-center ml-[45px] w-[660px] flex justify-between">
|
<div class="item-center ml-[45px] w-[660px] flex justify-between">
|
||||||
<nuxt-link
|
<nuxt-link
|
||||||
v-for="(item, index) in menuItems"
|
v-for="(item, index) in tdkList"
|
||||||
:key="index"
|
:key="index"
|
||||||
:to="item.path"
|
:to="item.path"
|
||||||
class="parent-links relative rounded-lg px-3 py-2 text-[#1A65FF]"
|
class="parent-links relative rounded-lg px-3 py-2 text-[#1A65FF]"
|
||||||
>
|
>
|
||||||
{{ item.name }}
|
{{ item.remark }}
|
||||||
<img v-if="item.path === '/communication/channel'" src="~/assets/images/hot.png" alt="火" class="absolute right-[-15px] top-[-2px]" />
|
<img v-if="item.path === '/channel'" src="~/assets/images/hot.png" alt="火" class="absolute right-[-12px] top-[0px]" />
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -31,19 +31,29 @@
|
|||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import useUserStore from '~/stores/user'
|
import useUserStore from '~/stores/user'
|
||||||
|
import { getTDKList } from '~/api/home/index'
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
import { BellFilled } from '@element-plus/icons-vue'
|
import { BellFilled } from '@element-plus/icons-vue'
|
||||||
import { ref, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
const menuItems = ref([
|
// const menuItems = ref([
|
||||||
{ name: '首页', path: '/' },
|
// { name: '首页', path: '/' },
|
||||||
{ name: '图纸', path: '/drawe' },
|
// { name: '图纸', path: '/drawe' },
|
||||||
{ name: '文本', path: '/text' },
|
// { name: '文本', path: '/text' },
|
||||||
{ name: '模型', path: '/model' },
|
// { name: '模型', path: '/model' },
|
||||||
{ name: '国外专区', path: '/foreign' },
|
// { name: '国外专区', path: '/foreign' },
|
||||||
{ name: '工具箱', path: '/toolbox' },
|
// { name: '工具箱', path: '/toolbox' },
|
||||||
{ name: '交流频道', path: '/channel' },
|
// { name: '交流频道', path: '/channel' },
|
||||||
// { name: '牛人社区', path: '/community' },
|
// // { name: '牛人社区', path: '/community' },
|
||||||
])
|
// ])
|
||||||
|
|
||||||
|
const { data: tdkList } = await useAsyncData('get-tdk-list-home', async () => {
|
||||||
|
const res = await getTDKList()
|
||||||
|
// 添加首页
|
||||||
|
if (!res.data.find((c) => c.remark === '首页')) {
|
||||||
|
res.data.unshift({ remark: '首页', path: '/' })
|
||||||
|
}
|
||||||
|
return res.data
|
||||||
|
})
|
||||||
|
|
||||||
// 是否登录
|
// 是否登录
|
||||||
const isLogin = computed(() => {
|
const isLogin = computed(() => {
|
||||||
@ -52,12 +62,12 @@
|
|||||||
|
|
||||||
// 用户中心
|
// 用户中心
|
||||||
const handleUserCenter = () => {
|
const handleUserCenter = () => {
|
||||||
navigateTo('/personal-Center/info')
|
navigateTo('/personal-center/info')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 消息中心
|
// 消息中心
|
||||||
const handleMessageCenter = () => {
|
const handleMessageCenter = () => {
|
||||||
navigateTo('/personal-Center/message-center')
|
navigateTo('/personal-center/message-center')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@ -3,7 +3,9 @@
|
|||||||
<div class="relative ma-auto flex items-center py-[20px] w-[1500px]!">
|
<div class="relative ma-auto flex items-center py-[20px] w-[1500px]!">
|
||||||
<img src="~/assets/images/logo5.png" alt="图夕夕" srcset="" class="h-[51px] w-[182px] cursor-pointer" @click="navigateTo('/')" />
|
<img src="~/assets/images/logo5.png" alt="图夕夕" srcset="" class="h-[51px] w-[182px] cursor-pointer" @click="navigateTo('/')" />
|
||||||
<div class="ml-[60px] flex items-center">
|
<div class="ml-[60px] flex items-center">
|
||||||
<span v-for="item in navList" :key="item" class="nav" :class="props.active === item ? 'active' : ''" @click="handleClick(item)">{{ item }}</span>
|
<span v-for="item in tdkList" :key="item.id" class="nav" :class="props.active === item.remark ? 'active' : ''" @click="handleClick(item.path)">{{
|
||||||
|
item.remark
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="relative ml-[30px]">
|
<div class="relative ml-[30px]">
|
||||||
<el-input
|
<el-input
|
||||||
@ -11,7 +13,7 @@
|
|||||||
placeholder="电子产品"
|
placeholder="电子产品"
|
||||||
:prefix-icon="Search"
|
:prefix-icon="Search"
|
||||||
class="search-input h-[40px] w-[328px]"
|
class="search-input h-[40px] w-[328px]"
|
||||||
@focus="handleHot(), (showHotList = true)"
|
@focus="(handleHot(), (showHotList = true))"
|
||||||
@input="handleInput"
|
@input="handleInput"
|
||||||
></el-input>
|
></el-input>
|
||||||
<!-- 搜索框 获取到焦点 显示热门列表 -->
|
<!-- 搜索框 获取到焦点 显示热门列表 -->
|
||||||
@ -38,11 +40,11 @@
|
|||||||
<div class="absolute right-[10px] flex items-center">
|
<div class="absolute right-[10px] flex items-center">
|
||||||
<div class="h-[36px] w-[36px] border-rd-[50%] bg-[#F5F5F5] text-center line-height-[44px]">
|
<div class="h-[36px] w-[36px] border-rd-[50%] bg-[#F5F5F5] text-center line-height-[44px]">
|
||||||
<img v-if="!isLogin" src="~/assets/images/user.png" alt="" srcset="" class="h-[19px] w-[17px] relative top-[0px] left-[0px]" />
|
<img v-if="!isLogin" src="~/assets/images/user.png" alt="" srcset="" class="h-[19px] w-[17px] relative top-[0px] left-[0px]" />
|
||||||
<img v-else :src="userStore.userInfoRes.avatar" alt="" srcset="" class="h-[19px] w-[17px] rd-[50%]" />
|
<img v-else :src="userStore.userInfoRes.avatar" alt="" srcset="" class="h-full w-full rd-[50%]" />
|
||||||
</div>
|
</div>
|
||||||
<span v-if="!isLogin" class="ml-[14px] cursor-pointer text-[14px] text-[#1A65FF] font-normal" @click="handleLogin">立即登录</span>
|
<span v-if="!isLogin" class="ml-[14px] cursor-pointer text-[14px] text-[#1A65FF] font-normal" @click="handleLogin">立即登录</span>
|
||||||
<el-dropdown v-else placement="top-start" @command="handleCommand">
|
<el-dropdown v-else placement="top-start" @command="handleCommand">
|
||||||
<span class="ml-[14px] cursor-pointer text-[14px] text-[#1A65FF] font-normal">{{ userStore.userInfoRes.nickname || '立即登录' }}</span>
|
<span class="ml-[10px] cursor-pointer text-[14px] text-[#1A65FF] font-normal">{{ userStore.userInfoRes.nickname || '立即登录' }}</span>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item command="个人中心"
|
<el-dropdown-item command="个人中心"
|
||||||
@ -64,14 +66,14 @@
|
|||||||
import { ref, getCurrentInstance, computed, onMounted } from 'vue'
|
import { ref, getCurrentInstance, computed, onMounted } from 'vue'
|
||||||
import { Setting, SwitchButton } from '@element-plus/icons-vue'
|
import { Setting, SwitchButton } from '@element-plus/icons-vue'
|
||||||
import { page } from '~/api/upnew/index'
|
import { page } from '~/api/upnew/index'
|
||||||
import { top } from '~/api/home/index'
|
import { top, getTDKList } from '~/api/home/index'
|
||||||
import type { ProjectDrawStatisticAppRespVO } from '~/api/home/type'
|
import type { ProjectDrawStatisticAppRespVO } from '~/api/home/type'
|
||||||
import { Search } from '@element-plus/icons-vue'
|
import { Search } from '@element-plus/icons-vue'
|
||||||
import refreshToken from "~/utils/RefreshToken";
|
import refreshToken from '~/utils/RefreshToken'
|
||||||
import useUserStore from '~/stores/user'
|
import useUserStore from '~/stores/user'
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const app = useNuxtApp()
|
const app = useNuxtApp()
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
active: {
|
active: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -92,7 +94,15 @@
|
|||||||
return !!userStore.token
|
return !!userStore.token
|
||||||
})
|
})
|
||||||
|
|
||||||
const navList = ref(['首页', '图纸', '文本', '模型', '国外专区', '工具箱', '交流频道'])
|
const { data: tdkList } = await useAsyncData('get-tdk-list-nav', async () => {
|
||||||
|
const res = await getTDKList()
|
||||||
|
// 添加首页
|
||||||
|
if (!res.data.find((c) => c.remark === '首页')) {
|
||||||
|
res.data.unshift({ remark: '首页', path: '/' })
|
||||||
|
}
|
||||||
|
return res.data
|
||||||
|
})
|
||||||
|
// const navList = ref(['首页', '图纸', '文本', '模型', '国外专区', '工具箱', '交流频道'])
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const handleHot = async () => {
|
const handleHot = async () => {
|
||||||
@ -131,47 +141,23 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleHotItem = (item: ProjectDrawStatisticAppRespVO) => {
|
const handleHotItem = (item: ProjectDrawStatisticAppRespVO) => {
|
||||||
const normal = { id: '0', name: '图纸库', isChildren: false }
|
// const normal = { id: '0', name: '图纸库', isChildren: false }
|
||||||
const level = item.pairs?.filter(Boolean).map((item) => ({ id: item?.id, name: item?.name, isChildren: false })) || []
|
// const level = item.pairs?.filter(Boolean).map((item) => ({ id: item?.id, name: item?.name, isChildren: false })) || []
|
||||||
level.unshift(normal)
|
// level.unshift(normal)
|
||||||
if (item.type === 1) {
|
if (item.type === 1) {
|
||||||
navigateTo(`/drawe?level=${JSON.stringify(level)}&keywords=${item.title || ''}`)
|
navigateTo(`/drawe/${item.projectType}/1/12/-1`)
|
||||||
|
// navigateTo(`/drawe?level=${JSON.stringify(level)}&keywords=${item.title || ''}`)
|
||||||
} else if (item.type === 2) {
|
} else if (item.type === 2) {
|
||||||
navigateTo(`/text?level=${JSON.stringify(level)}&keywords=${item.title || ''}`)
|
navigateTo(`/text/${item.projectType}/1/12/-1`)
|
||||||
|
// navigateTo(`/text?level=${JSON.stringify(level)}&keywords=${item.title || ''}`)
|
||||||
} else if (item.type === 3) {
|
} else if (item.type === 3) {
|
||||||
navigateTo(`/model?level=${JSON.stringify(level)}&keywords=${item.title || ''}`)
|
navigateTo(`/model/${item.projectType}/1/12/-1`)
|
||||||
|
// navigateTo(`/model?level=${JSON.stringify(level)}&keywords=${item.title || ''}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleClick = (item: string) => {
|
const handleClick = (item: string) => {
|
||||||
switch (item) {
|
navigateTo(item)
|
||||||
case '首页':
|
|
||||||
navigateTo({ path: '/'}) // 修改为在新窗口打开
|
|
||||||
break
|
|
||||||
case '图纸':
|
|
||||||
navigateTo('/drawe') // 修改为在新窗口打开
|
|
||||||
break
|
|
||||||
case '文本':
|
|
||||||
navigateTo('/text') // 修改为在新窗口打开
|
|
||||||
break
|
|
||||||
case '模型':
|
|
||||||
navigateTo('/model') // 修改为在新窗口打开
|
|
||||||
break
|
|
||||||
case '国外专区':
|
|
||||||
navigateTo('/foreign') // 修改为在新窗口打开
|
|
||||||
break
|
|
||||||
case '牛人社区':
|
|
||||||
navigateTo('/community') // 修改为在新窗口打开
|
|
||||||
break
|
|
||||||
case '交流频道':
|
|
||||||
navigateTo('/channel') // 修改为在新窗口打开
|
|
||||||
break
|
|
||||||
case '工具箱':
|
|
||||||
navigateTo('/toolbox') // 修改为在新窗口打开
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const handleLogin = () => {
|
const handleLogin = () => {
|
||||||
app?.$openLogin() // 调用全局方法
|
app?.$openLogin() // 调用全局方法
|
||||||
@ -182,7 +168,7 @@
|
|||||||
userStore.logout()
|
userStore.logout()
|
||||||
userStore.$reset()
|
userStore.$reset()
|
||||||
} else if (command === '个人中心') {
|
} else if (command === '个人中心') {
|
||||||
navigateTo('/personal-Center/info')
|
navigateTo('/personal-center/info')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
<!-- <div class="vip-card-subtitle">中小微企业</div> -->
|
<!-- <div class="vip-card-subtitle">中小微企业</div> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="vip-card-price">
|
<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>
|
<span class="per">/1年</span>
|
||||||
</div>
|
</div>
|
||||||
<ul class="vip-card-features">
|
<ul class="vip-card-features">
|
||||||
@ -36,7 +36,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch, onMounted } from 'vue'
|
import { ref, watch, onMounted } from 'vue'
|
||||||
import { listVip, submitPayOrder, getPayStatus } from '~/api/pay/index'
|
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 { Close } from '@element-plus/icons-vue'
|
||||||
import type { AppPayWalletPackageRespVO } from '~/api/pay/types'
|
import type { AppPayWalletPackageRespVO } from '~/api/pay/types'
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@ -153,8 +153,10 @@
|
|||||||
.vip-cards {
|
.vip-cards {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 32px;
|
gap: 32px;
|
||||||
justify-content: center;
|
/* justify-content: center; */
|
||||||
margin: 24px 0;
|
margin: 24px 0;
|
||||||
|
overflow-x: auto;
|
||||||
|
padding: 10px;
|
||||||
}
|
}
|
||||||
.vip-card {
|
.vip-card {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="fixed-button-group">
|
<div class="fixed-button-group">
|
||||||
<div class="button-item" @click="handleVip">
|
<div class="button-item" @click="handleVip">
|
||||||
<el-badge :is-dot="readCount" class="item">
|
<el-badge class="item">
|
||||||
<el-icon class="icon-item !color-[#10c55b]"><Trophy /></el-icon>
|
<el-icon class="icon-item !color-[#10c55b]"><Trophy /></el-icon>
|
||||||
</el-badge>
|
</el-badge>
|
||||||
<span class="button-text">VIP</span>
|
<span class="button-text">VIP</span>
|
||||||
|
|||||||
@ -1,20 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<header class="h-106px">
|
<header class="h-[106px]">
|
||||||
<div class="mx-a ml--250px h-full flex items-center justify-center">
|
<div class="mx-a ml-[-250px] h-full flex items-center justify-center">
|
||||||
<!-- Logo区域 -->
|
<!-- Logo区域 -->
|
||||||
<div class="h-100% flex cursor-pointer items-center" @click="navigateTo('/')">
|
<div class="h-[100%] flex cursor-pointer items-center" @click="navigateTo('/')">
|
||||||
<img src="~/assets/images/logo5.png" alt="图夕夕" class="h-51px w-182px" />
|
<img src="~/assets/images/logo5.png" alt="图夕夕" class="h-[51px] w-[182px]" />
|
||||||
</div>
|
</div>
|
||||||
<!-- 搜索区域 -->
|
<!-- 搜索区域 -->
|
||||||
<div class="relative ml-49px w-647px px4 p-r-0px!">
|
<div class="relative ml-[49px] w-[647px] px-4 p-r-[0px]!">
|
||||||
<div class="search-input relative w-100%">
|
<div class="search-input relative w-[100%]">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="searchQuery"
|
v-model="searchQuery"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="搜一搜"
|
placeholder="搜一搜"
|
||||||
:prefix-icon="Search"
|
:prefix-icon="Search"
|
||||||
class="no-right-border box-border h-40px w-100% rounded-bl-4px rounded-br-0px rounded-tl-4px rounded-tr-0px bg-[#F8F8F8] text-14px outline-#999"
|
class="no-right-border box-border h-[40px] w-[100%] rounded-bl-[4px] rounded-br-[0px] rounded-tl-[4px] rounded-tr-[0px] bg-[#F8F8F8] text-[14px] outline-[#999]"
|
||||||
@focus="handleHot(), (showHotList = true)"
|
@focus="handleHot(), (showHotList = true)"
|
||||||
@input="handleInput"
|
@input="handleInput"
|
||||||
/>
|
/>
|
||||||
@ -23,32 +23,32 @@
|
|||||||
<div
|
<div
|
||||||
v-if="showHotList"
|
v-if="showHotList"
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
class="absolute z-100 w-625px border-width-1px border-color-#1A65FF rounded-bl-4px rounded-br-4px rounded-tl-0px rounded-tr-0px border-solid bg-[#fff] pa-10px"
|
class="absolute z-100 w-[625px] border-width-[1px] border-color-[#1A65FF] rounded-bl-[4px] rounded-br-[4px] rounded-tl-[0px] rounded-tr-[0px] border-solid bg-[#fff] pa-[10px]"
|
||||||
>
|
>
|
||||||
<!-- 这里放置热门列表的内容 -->
|
<!-- 这里放置热门列表的内容 -->
|
||||||
<ul class="flex flex-col gap-6px">
|
<ul class="flex flex-col gap-[6px]">
|
||||||
<li
|
<li
|
||||||
v-for="(item, index) in hotItems"
|
v-for="(item, index) in hotItems"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="flex flex-row cursor-pointer items-center justify-between text-13px"
|
class="flex flex-row cursor-pointer items-center justify-between text-[13px]"
|
||||||
@click="handleHotItem(item)"
|
@click="handleHotItem(item)"
|
||||||
>
|
>
|
||||||
<span class="color-#333333">{{ item.projectTypeName }}</span>
|
<span class="color-[#333333]">{{ item.projectTypeName }}</span>
|
||||||
<span v-if="item.count" class="color-#999999">{{ item.count }}份图纸</span>
|
<span v-if="item.count" class="color-[#999999]">{{ item.count }}份图纸</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div v-if="!hotItems.length" class="text-12px color-#999">无数据</div>
|
<div v-if="!hotItems.length" class="text-[12px] color-[#999]">无数据</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 按钮区域 -->
|
<!-- 按钮区域 -->
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<button
|
<button
|
||||||
class="h-40px w-111px cursor-pointer border-width-1px border-color-#1A65FF rounded-bl-0px rounded-br-4px rounded-tl-0px rounded-tr-4px border-none border-solid text-center text-14px color-#fff bg-#1A65FF!"
|
class="h-[40px] w-[111px] cursor-pointer border-width-[1px] border-color-[#1A65FF] rounded-bl-[0px] rounded-br-[4px] rounded-tl-[0px] rounded-tr-[4px] border-none border-solid text-center text-[14px] color-[#fff] !bg-[#1A65FF]"
|
||||||
>
|
>
|
||||||
搜索
|
搜索
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="m-l-16px h-40px w-111px cursor-pointer border-width-1px border-color-#E7B03B rounded-bl-6px rounded-br-6px rounded-tl-4px rounded-tr-6px border-none border-solid text-14px color-#fff bg-#E7B03B!"
|
class="m-l-[16px] h-[40px] w-[111px] cursor-pointer border-width-[1px] border-color-[#E7B03B] rounded-bl-[6px] rounded-br-[6px] rounded-tl-[4px] rounded-tr-[6px] border-none border-solid text-[14px] color-[#fff] !bg-[#E7B03B]"
|
||||||
@click="handleUpload"
|
@click="handleUpload"
|
||||||
>
|
>
|
||||||
上传图纸
|
上传图纸
|
||||||
@ -76,7 +76,7 @@
|
|||||||
// 是否登录
|
// 是否登录
|
||||||
if (!userStore.token) return ElMessage.error('请先登录')
|
if (!userStore.token) return ElMessage.error('请先登录')
|
||||||
// 新开窗口 用router跳转 新窗口打开
|
// 新开窗口 用router跳转 新窗口打开
|
||||||
navigateTo('/upnew/drawe')
|
navigateTo('/upnew')
|
||||||
}
|
}
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
@ -116,16 +116,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleHotItem = (item: ProjectDrawStatisticAppRespVO) => {
|
const handleHotItem = (item: ProjectDrawStatisticAppRespVO) => {
|
||||||
const normal = { id: '0', name: '图纸库', isChildren: false }
|
// const normal = { id: '0', name: '图纸库', isChildren: false }
|
||||||
const level = item.pairs?.filter(Boolean).map((item) => ({ id: item?.id, name: item?.name, isChildren: false })) || []
|
// const level = item.pairs?.filter(Boolean).map((item) => ({ id: item?.id, name: item?.name, isChildren: false })) || []
|
||||||
level.unshift(normal)
|
// level.unshift(normal)
|
||||||
if (item.type === 1) {
|
// if (item.type === 1) {
|
||||||
navigateTo(`/drawe?level=${JSON.stringify(level)}&keywords=${item.title || ''}`,)
|
// navigateTo(`/drawe?level=${JSON.stringify(level)}&keywords=${item.title || ''}`,)
|
||||||
} else if (item.type === 2) {
|
// } else if (item.type === 2) {
|
||||||
navigateTo(`/text?level=${JSON.stringify(level)}&keywords=${item.title || ''}`,)
|
// navigateTo(`/text?level=${JSON.stringify(level)}&keywords=${item.title || ''}`,)
|
||||||
} else if (item.type === 3) {
|
// } else if (item.type === 3) {
|
||||||
navigateTo(`/model?level=${JSON.stringify(level)}&keywords=${item.title || ''}`,)
|
// navigateTo(`/model?level=${JSON.stringify(level)}&keywords=${item.title || ''}`,)
|
||||||
}
|
// }
|
||||||
|
navigateTo(`/drawe/${item.projectType}/1/12/-1`)
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
>
|
>
|
||||||
<el-tab-pane v-for="(item, index) in data" :key="index" :label="item.label" :name="item.value">
|
<el-tab-pane v-for="(item, index) in data" :key="index" :label="item.label" :name="item.value">
|
||||||
<template v-if="showNum" #label>
|
<template v-if="showNum" #label>
|
||||||
<img v-if="item.value === tabActive && showIcon" src="~/assets/images/2.png" alt="" srcset="" class="mr-7px" />
|
<img v-if="item.value === tabActive && showIcon" src="~/assets/images/2.png" alt="" srcset="" class="mr-[7px]" />
|
||||||
<span>{{ item.label }}</span>
|
<span>{{ item.label }}</span>
|
||||||
<el-badge :value="item.num" class="item" :max="9999999999999" :hidden="!item.num" />
|
<el-badge :value="item.num" class="item" :max="9999999999999" :hidden="!item.num" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
47
components/kl-tab-bar/v3/index.vue
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<template>
|
||||||
|
<div class="flex items-center gap-[50px] mb-[20px]">
|
||||||
|
<el-link
|
||||||
|
v-for="(item, index) in props.data"
|
||||||
|
:key="index"
|
||||||
|
class="text-[15px]!"
|
||||||
|
:underline="modelValue === item.value ? 'always' : 'never'"
|
||||||
|
:type="modelValue === item.value ? 'primary' : 'info'"
|
||||||
|
@click="handleChange(item)"
|
||||||
|
>
|
||||||
|
{{ item.label }}
|
||||||
|
</el-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { PropType } from 'vue'
|
||||||
|
const props = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Array as PropType<{ num?: number; label: string; value: string | number; [key: string]: any }[]>,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const emits = defineEmits(['change'])
|
||||||
|
|
||||||
|
const modelValue = defineModel<any>('modelValue', {
|
||||||
|
required: true,
|
||||||
|
}) // 双向绑定的value
|
||||||
|
|
||||||
|
const handleChange = (value: { value: string | number; [key: string]: any }) => {
|
||||||
|
modelValue.value = value.value
|
||||||
|
emits('change', value)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
:deep(.el-link.is-underline) {
|
||||||
|
&::hover {
|
||||||
|
color: #1a65ff !important; // 鼠标悬停时的颜色
|
||||||
|
}
|
||||||
|
&::after {
|
||||||
|
bottom: -3px;
|
||||||
|
border-bottom: 2px solid #1a65ff; // 去掉下划线
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -323,7 +323,7 @@
|
|||||||
|
|
||||||
// 判断是否是图片
|
// 判断是否是图片
|
||||||
const handelFileType = (fileName: string) => {
|
const handelFileType = (fileName: string) => {
|
||||||
const ext = fileName.split('.').pop()?.toLowerCase() || ''
|
const ext = fileName?.split('.').pop()?.toLowerCase() || ''
|
||||||
return ['png', 'jpg', 'jpeg'].includes(ext)
|
return ['png', 'jpg', 'jpeg'].includes(ext)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- 面包屑 -->
|
<!-- 面包屑 -->
|
||||||
<div v-if="level.length > 1" class="mb-[-10px] mt-[20px] pl-[20px]">
|
<div v-if="breadList && breadList.length > 1" class="mb-[-10px] mt-[20px] pl-[20px]">
|
||||||
<el-breadcrumb :separator-icon="ArrowRight">
|
<el-breadcrumb :separator-icon="ArrowRight">
|
||||||
<el-breadcrumb-item v-for="(item, index) in level" :key="item.name" class="cursor-pointer" @click="handleClickBread(item, index)">{{
|
<el-breadcrumb-item v-for="(item, index) in breadList" :key="item.name" class="cursor-pointer" @click="handleClickBread(item, index)">{{
|
||||||
item.name
|
item.name
|
||||||
}}</el-breadcrumb-item>
|
}}</el-breadcrumb-item>
|
||||||
</el-breadcrumb>
|
</el-breadcrumb>
|
||||||
@ -75,24 +75,38 @@
|
|||||||
const query = defineModel<pageReq>('modelValue', {
|
const query = defineModel<pageReq>('modelValue', {
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
const level = defineModel<{ id: string; name: string; isChildren?: boolean }[]>('level', {
|
// const level = defineModel<{ id: string; name: string; isChildren?: boolean }[]>('level', {
|
||||||
required: true,
|
// required: true,
|
||||||
})
|
// })
|
||||||
|
|
||||||
const computType = computed(() => {
|
const computType = computed(() => {
|
||||||
return props.type === 1 ? '图纸' : props.type === 3 ? '模型' : '文本'
|
return props.type === 1 ? '图纸' : props.type === 3 ? '模型' : '文本'
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleParentId = (type?: string) => {
|
/** 版本 */
|
||||||
if (level?.value?.length > 1) {
|
const { data: editionsList } = useAsyncData(`editionsList-${props.type}}`, async () => {
|
||||||
if (type === 'init' && level.value.find((c: any) => c.isChildren)) {
|
const res = await parent({ type: 2, parentId: 0 })
|
||||||
return level.value[level.value.length - 2].id || '' // 获取最后一个元素的 id 或 defaul
|
const all = [{ id: '-1', name: '全部' }]
|
||||||
}
|
return [...all, ...res.data]
|
||||||
return level.value[level.value.length - 1].id || '' // 获取最后一个元素的 id 或 defaul
|
})
|
||||||
}
|
|
||||||
return '0'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// 获取面包屑
|
||||||
|
const { data: breadList } = await useAsyncData(
|
||||||
|
`breadList-${props.type}-${props.id}-${query.value.projectType}}`,
|
||||||
|
async () => {
|
||||||
|
const res = await getDictTree({ type: 1, id: query.value.projectType })
|
||||||
|
const all = [
|
||||||
|
{
|
||||||
|
id: -1,
|
||||||
|
name: props.type === 1 ? '图纸库' : props.type === 3 ? '模型库' : '文本库',
|
||||||
|
isChildren: false,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const arr = [...res.data, ...all]
|
||||||
|
return arr.reverse()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// const projectTypeList = ref<any>([])
|
// const projectTypeList = ref<any>([])
|
||||||
/** 获取分类下拉框 */
|
/** 获取分类下拉框 */
|
||||||
// const getParent = (type?: string) => {
|
// const getParent = (type?: string) => {
|
||||||
@ -121,55 +135,72 @@
|
|||||||
// }
|
// }
|
||||||
// getEditionsList()
|
// getEditionsList()
|
||||||
|
|
||||||
// 获取面包屑
|
console.log('breadList.value.length----', breadList.value);
|
||||||
const {data: breadList} = await useAsyncData(`breadList-${props.type}-${props.id}-${props.groundId}-${Date.now()}`, async () => {
|
|
||||||
const res = await getDictTree({ type: props.type, id: query.value.projectType })
|
|
||||||
return res.data
|
|
||||||
})
|
|
||||||
|
|
||||||
console.log('breadList', breadList);
|
// 服务端渲染兼容方案:顺序执行异步操作
|
||||||
|
// 1. 先获取面包屑数据(已在上面通过useAsyncData获取)
|
||||||
|
|
||||||
|
// 2. 顺序获取分类下拉框数据
|
||||||
|
// 创建一个函数来获取分类数据,确保服务端渲染时能获取到数据
|
||||||
|
const getProjectTypeList = async () => {
|
||||||
|
let parentId: any = '0'
|
||||||
|
|
||||||
|
// 计算parentId的逻辑
|
||||||
|
if (breadList?.value && breadList?.value.length > 1) {
|
||||||
|
if (breadList.value.length > 2) {
|
||||||
|
const length = breadList.value?.length
|
||||||
|
parentId = breadList?.value[length - 2].id
|
||||||
|
} else {
|
||||||
|
const length = breadList.value?.length
|
||||||
|
parentId = breadList?.value[length - 1].id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('parentId', parentId);
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 获取分类数据
|
||||||
|
const res = await parent({ type: 1, parentId: parentId })
|
||||||
|
const all = [{ id: parentId === '0' ? '-1' : parentId, name: '全部' }]
|
||||||
|
return [...all, ...res.data]
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取分类数据失败:', error)
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用useAsyncData获取分类列表,确保服务端渲染兼容性
|
||||||
|
const { data: projectTypeList } = await useAsyncData(
|
||||||
|
`projectType-draw-${props.type}-${query.value.projectType}}`,
|
||||||
|
getProjectTypeList,
|
||||||
|
{ server: true } // 确保在服务端执行
|
||||||
|
)
|
||||||
|
|
||||||
/** 是否是初始化 */
|
|
||||||
const queryType = ref('init')
|
|
||||||
/**获取分类下拉框 */
|
|
||||||
const { data: projectTypeList, refresh } = useAsyncData(`projectType-draw-${props.type}-${Date.now()}`, async () => {
|
|
||||||
const res = await parent({ type: 1, parentId: handleParentId(queryType.value) })
|
|
||||||
const all = [{ id: '-1', name: '全部' }]
|
|
||||||
return [...all, ...res.data]
|
|
||||||
})
|
|
||||||
|
|
||||||
/** 版本 */
|
|
||||||
const { data: editionsList } = useAsyncData(`editionsList-${props.type}-${Date.now()}`, async () => {
|
|
||||||
const res = await parent({ type: 2, parentId: 0 })
|
|
||||||
const all = [{ id: '-1', name: '全部' }]
|
|
||||||
return [...all, ...res.data]
|
|
||||||
})
|
|
||||||
|
|
||||||
const handleClick = (row: any) => {
|
const handleClick = (row: any) => {
|
||||||
query.value.title = ''
|
query.value.title = ''
|
||||||
query.value.projectType = row.id
|
query.value.projectType = row.id
|
||||||
if (row.name === '全部') return
|
// if (row.name === '全部') return
|
||||||
const isChildren = level.value.find((c: any) => c.isChildren)
|
// const isChildren = breadList.value.find((c: any) => c.isChildren)
|
||||||
if (!row.isChildren && isChildren) {
|
// if (!row.isChildren && isChildren) {
|
||||||
const index = level.value.length - 1
|
// const index = breadList.value.length - 1
|
||||||
level.value[index] = { id: row.id, name: row.name, isChildren: true }
|
// breadList.value[index] = { id: row.id, name: row.name, isChildren: true }
|
||||||
} else if (!row.isChildren && !isChildren) {
|
// } else if (!row.isChildren && !isChildren) {
|
||||||
level.value.push({ id: row.id, name: row.name, isChildren: true })
|
// breadList.value.push({ id: row.id, name: row.name, isChildren: true })
|
||||||
} else {
|
// } else {
|
||||||
level.value.push({ id: row.id, name: row.name })
|
// breadList.value.push({ id: row.id, name: row.name })
|
||||||
// getParent()
|
// // getParent()
|
||||||
queryType.value = ''
|
// refresh()
|
||||||
refresh()
|
// }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleClickBread = (row: any, index: number) => {
|
const handleClickBread = (row: any, index: number) => {
|
||||||
level.value.splice(index + 1)
|
// breadList.value.splice(index + 1)
|
||||||
query.value.title = ''
|
query.value.title = ''
|
||||||
query.value.projectType = row.id
|
query.value.projectType = row.id
|
||||||
// getParent()
|
// getParent()
|
||||||
queryType.value = ''
|
// refresh()
|
||||||
refresh()
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
181
components/m/RecommendItem/index.vue
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
<template>
|
||||||
|
<view class="design-list">
|
||||||
|
<view class="design-item" v-for="(item, index) in items" :key="index">
|
||||||
|
<view class="design-preview">
|
||||||
|
<image :src="item.image" mode="aspectFit"></image>
|
||||||
|
</view>
|
||||||
|
<view class="design-info">
|
||||||
|
<view class="design-title">{{ item.title }}</view>
|
||||||
|
<view class="design-author">by:{{ item.author }}</view>
|
||||||
|
|
||||||
|
<view class="design-stats">
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="iconfont">👁</text>
|
||||||
|
<text>{{ item.views }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="iconfont">👍</text>
|
||||||
|
<text>{{ item.likes }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="iconfont">💬</text>
|
||||||
|
<text>{{ item.comments }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="design-action">
|
||||||
|
<button class="view-btn">查看</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "RecommendItem",
|
||||||
|
props: {
|
||||||
|
currentTab: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title: "高压细水雾灭火推车描述",
|
||||||
|
author: "赵其",
|
||||||
|
image: "/static/images/activity1.png",
|
||||||
|
views: 128,
|
||||||
|
likes: 16,
|
||||||
|
comments: 35,
|
||||||
|
url: "/pages/drawings/detail?id=1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
title: "高压细水雾灭火推车描述",
|
||||||
|
author: "赵其",
|
||||||
|
image: "/static/images/activity2.png",
|
||||||
|
views: 128,
|
||||||
|
likes: 16,
|
||||||
|
comments: 35,
|
||||||
|
url: "/pages/drawings/detail?id=2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title: "室内CAD模型设计室内CAD模型设计",
|
||||||
|
author: "张泽",
|
||||||
|
image: "/static/images/activity1.png",
|
||||||
|
views: 95,
|
||||||
|
likes: 12,
|
||||||
|
comments: 28,
|
||||||
|
url: "/pages/models/detail?id=1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title: "CAD设计规范文档",
|
||||||
|
author: "李华",
|
||||||
|
image: "/static/images/activity2.png",
|
||||||
|
views: 156,
|
||||||
|
likes: 23,
|
||||||
|
comments: 42,
|
||||||
|
url: "/pages/documents/detail?id=1",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
viewDetail(item) {
|
||||||
|
console.log("View detail for:", item.title);
|
||||||
|
uni.navigateTo({
|
||||||
|
url: item.url,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
// 变量定义
|
||||||
|
$primary-color: #007aff;
|
||||||
|
$text-color: #333;
|
||||||
|
$secondary-text: #666;
|
||||||
|
$light-text: #999;
|
||||||
|
$bg-color: #f0f4f9;
|
||||||
|
$white: #fff;
|
||||||
|
$border-color: #eee;
|
||||||
|
$border-radius: 15rpx;
|
||||||
|
.design-list {
|
||||||
|
// padding: 10rpx 20rpx;
|
||||||
|
|
||||||
|
.design-item {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
background-color: $white;
|
||||||
|
border-radius: $border-radius;
|
||||||
|
border: 1px solid $border-color;
|
||||||
|
padding: 17rpx 10rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: relative;
|
||||||
|
box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
|
.design-preview {
|
||||||
|
width: 220rpx;
|
||||||
|
height: 168rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.design-info {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
|
||||||
|
.design-title {
|
||||||
|
font-size: 27rpx;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.design-author {
|
||||||
|
font-size: 25rpx;
|
||||||
|
color: $light-text;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.design-stats {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.stat-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: $light-text;
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
margin-right: 5rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.design-action {
|
||||||
|
position: absolute;
|
||||||
|
right: 20rpx;
|
||||||
|
bottom: 20rpx;
|
||||||
|
|
||||||
|
.view-btn {
|
||||||
|
background-color: $primary-color;
|
||||||
|
color: $white;
|
||||||
|
font-size: 25rpx;
|
||||||
|
padding: 0rpx 25rpx !important;
|
||||||
|
border-radius: 5rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
16
components/m/detail-components/Works.vue
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<template>
|
||||||
|
<div class="works">
|
||||||
|
<RecommendList />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
defineOptions({ name: 'Works' })
|
||||||
|
import RecommendList from "~/components/m/RecommendItem/index.vue";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.works {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
73
components/m/detail-components/certificates.vue
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="cert-item"
|
||||||
|
v-for="(cert, index) in talentInfo.certificates"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-if="index !== talentInfo.certificates.length - 1"
|
||||||
|
class="border-left"
|
||||||
|
></div>
|
||||||
|
<div class="cert-dot"></div>
|
||||||
|
<div class="cert-info">
|
||||||
|
<span class="cert-year">{{ cert.year }}</span>
|
||||||
|
<span class="cert-desc">{{ cert.description }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
defineOptions({ name: 'Certificates' })
|
||||||
|
interface Certificate { year: string; description: string }
|
||||||
|
interface TalentInfo { certificates: Certificate[] }
|
||||||
|
defineProps<{ talentInfo: TalentInfo }>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.border-left {
|
||||||
|
width: 1px;
|
||||||
|
height: calc(100%);
|
||||||
|
border-left: 2px dotted #e6f0ff;
|
||||||
|
position: absolute;
|
||||||
|
left: 7rpx;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
// 证书列表
|
||||||
|
.cert-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cert-dot {
|
||||||
|
width: 16rpx;
|
||||||
|
height: 16rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #1a65ff;
|
||||||
|
// margin-top: 12rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cert-info {
|
||||||
|
flex: 1;
|
||||||
|
margin-bottom: 11rpx;
|
||||||
|
margin-top: -10rpx;
|
||||||
|
padding-bottom: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cert-year {
|
||||||
|
font-size: 25rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cert-desc {
|
||||||
|
font-size: 21rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
35
components/m/detail-components/technicalCertificates.vue
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<template>
|
||||||
|
<div class="flex">
|
||||||
|
<div
|
||||||
|
class="cert-technicalCertificates"
|
||||||
|
v-for="(cert, index) in 10"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
class="cert-image"
|
||||||
|
:src="`https://picsum.photos/90/90?random=${index}`"
|
||||||
|
alt="certificate"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
defineOptions({ name: 'TechnicalCertificates' })
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 50rpx;
|
||||||
|
}
|
||||||
|
.cert-technicalCertificates {
|
||||||
|
width: 135rpx;
|
||||||
|
height: 191rpx;
|
||||||
|
.cert-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
201
components/m/nav-bar/index.vue
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 顶部导航栏 -->
|
||||||
|
<view class="nav-bar">
|
||||||
|
<view class="nav-item active">全部</view>
|
||||||
|
<view class="nav-item">机械设备</view>
|
||||||
|
<view class="nav-item">零部件模型</view>
|
||||||
|
<view class="nav-item">交通运输</view>
|
||||||
|
<view class="nav-item">电子产品</view>
|
||||||
|
<view class="expand-btn" @tap="toggleCategoryMenu">
|
||||||
|
<text class="expand-icon">≡</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 全部分类浮窗 -->
|
||||||
|
<view
|
||||||
|
class="category-popup"
|
||||||
|
v-if="showCategoryMenu"
|
||||||
|
@tap.stop="closeCategoryMenu"
|
||||||
|
>
|
||||||
|
<view class="popup-content" @tap.stop>
|
||||||
|
<view class="category-list">
|
||||||
|
<view
|
||||||
|
:key="index"
|
||||||
|
v-for="(section, index) in categoryList"
|
||||||
|
class="category-item"
|
||||||
|
@tap="selectCategory(section)"
|
||||||
|
>
|
||||||
|
{{ section.name }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 筛选选项 -->
|
||||||
|
<view class="filter-bar">
|
||||||
|
<view class="filter-item"> 软件分类 <text class="icon-down">∨</text> </view>
|
||||||
|
<view class="filter-item"> 图纸类型 <text class="icon-down">∨</text> </view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
showCategoryMenu: false,
|
||||||
|
categoryList: [
|
||||||
|
{ name: "机械设备", active: false },
|
||||||
|
{ name: "零部件模型", active: false },
|
||||||
|
{ name: "交通运输", active: false },
|
||||||
|
{ name: "电子产品", active: false },
|
||||||
|
{ name: "机械设备", active: false },
|
||||||
|
{ name: "零部件模型", active: false },
|
||||||
|
{ name: "交通运输", active: false },
|
||||||
|
{ name: "电子产品", active: false },
|
||||||
|
{ name: "机械设备", active: false },
|
||||||
|
{ name: "零部件模型", active: false },
|
||||||
|
{ name: "交通运输", active: false },
|
||||||
|
{ name: "电子产品", active: false },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggleCategoryMenu() {
|
||||||
|
this.showCategoryMenu = !this.showCategoryMenu;
|
||||||
|
},
|
||||||
|
closeCategoryMenu() {
|
||||||
|
this.showCategoryMenu = false;
|
||||||
|
},
|
||||||
|
selectCategory(section) {
|
||||||
|
// 演示用:显示toast提示
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onLoad(options) {
|
||||||
|
console.log(options);
|
||||||
|
// 监听点击事件,点击页面空白处关闭菜单
|
||||||
|
uni.$on("page-click", () => {
|
||||||
|
if (this.showCategoryMenu) {
|
||||||
|
this.closeCategoryMenu();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onUnload() {
|
||||||
|
// 移除事件监听
|
||||||
|
uni.$off("page-click");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
// 变量定义
|
||||||
|
$primary-color: #007aff;
|
||||||
|
$text-color: #333;
|
||||||
|
$secondary-text: #666;
|
||||||
|
$light-text: #999;
|
||||||
|
$bg-color: #fff;
|
||||||
|
$white: #fff;
|
||||||
|
$border-color: #eee;
|
||||||
|
$border-radius: 10rpx;
|
||||||
|
$mask-bg: rgba(0, 0, 0, 0.5);
|
||||||
|
.nav-bar {
|
||||||
|
display: flex;
|
||||||
|
background-color: $white;
|
||||||
|
padding: 10rpx 0;
|
||||||
|
position: relative;
|
||||||
|
padding-right: 60rpx;
|
||||||
|
|
||||||
|
.nav-item {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 25rpx;
|
||||||
|
padding: 15rpx 0;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: $primary-color;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.expand-btn {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 80rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.expand-icon {
|
||||||
|
font-size: 40rpx;
|
||||||
|
color: $text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分类浮窗样式
|
||||||
|
.category-popup {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: $mask-bg;
|
||||||
|
z-index: 999;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.popup-content {
|
||||||
|
width: 100%;
|
||||||
|
max-height: 80vh;
|
||||||
|
background-color: $white;
|
||||||
|
animation: slideDown 0.3s ease;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
.category-list {
|
||||||
|
padding: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
.category-item {
|
||||||
|
padding: 8rpx 12.94rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-right: 3%;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 25rpx;
|
||||||
|
background-color: $bg-color;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
border: 1px solid $border-color;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 滑入动画
|
||||||
|
@keyframes slideDown {
|
||||||
|
from {
|
||||||
|
transform: translateY(-100%);
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateY(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-bar {
|
||||||
|
display: flex;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
|
||||||
|
.filter-item {
|
||||||
|
margin-right: 30rpx;
|
||||||
|
font-size: 25rpx;
|
||||||
|
color: $secondary-text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-down {
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,8 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="relative mt-[34px] w-[100%]">
|
<div class="relative mt-[34px] w-[100%]">
|
||||||
<KlTabBar v-model="query.source" :data="tabBar" />
|
<KlTabBar v-model="query.source" :data="tabBar" />
|
||||||
<div class="absolute right-[0px] top-[10px] text-[16px] text-[#999999] font-normal"
|
<div class="absolute right-[0px] top-[0px] text-[16px] text-[#999999] font-normal">
|
||||||
>共<span class="color-[#1A65FF]">{{ result?.total }}</span
|
<el-button type="warning" class="mr-4px" @click="handleUpload">上传工具</el-button>
|
||||||
|
共<span class="color-[#1A65FF]">{{ result?.total }}</span
|
||||||
>个筛选结果</div
|
>个筛选结果</div
|
||||||
>
|
>
|
||||||
<div class="content mt-[10px]">
|
<div class="content mt-[10px]">
|
||||||
@ -17,16 +18,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import KlTabBar from '~/components/kl-tab-bar/index.vue'
|
import KlTabBar from '~/components/kl-tab-bar/v3/index.vue'
|
||||||
import CardPicture from '~/components/kl-card-picture/index.vue'
|
import CardPicture from '~/components/kl-card-picture/index.vue'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import type { pageRes, pageReq } from '~/api/upnew/types'
|
import type { pageRes, pageReq } from '~/api/upnew/types'
|
||||||
import emptyImg from '~/assets/images/empty.png'
|
import emptyImg from '~/assets/images/empty.png'
|
||||||
|
import useUserStore from '~/stores/user'
|
||||||
|
|
||||||
const query = defineModel<pageReq>('modelValue', {
|
const query = defineModel<pageReq>('modelValue', {
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
const result = defineModel<pageRes| null>('result', {
|
const result = defineModel<pageRes | null>('result', {
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -44,6 +46,15 @@
|
|||||||
value: 2,
|
value: 2,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
|
const handleUpload = () => {
|
||||||
|
// 先判断登录
|
||||||
|
const store = useUserStore()
|
||||||
|
if (!store.token) {
|
||||||
|
return ElMessage.error('请先登录')
|
||||||
|
}
|
||||||
|
navigateTo('/upnew?drawType=3')
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
useHead({
|
useHead({
|
||||||
title: `${props.title}`,
|
title: `${props.title}`,
|
||||||
meta: [
|
meta: [
|
||||||
{ name: 'description', content: props.description },
|
{ name: 'description', content: `${props.description}`},
|
||||||
{ name: 'keywords', content: props.keywords },
|
{ name: 'keywords', content: props.keywords },
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="relative mt-[34px] w-[100%]">
|
<div class="relative mt-[34px] w-[100%]">
|
||||||
<KlTabBar v-model="query.source" :data="tabBar" />
|
<KlTabBar v-model="query.source" :data="tabBar" />
|
||||||
<div class="absolute right-[0px] top-[10px] text-[16px] text-[#999999] font-normal"
|
<div class="absolute right-[0px] top-[0px] text-[16px] text-[#999999] font-normal">
|
||||||
>共<span class="color-[#1A65FF]">{{ result?.total }}</span
|
<el-button type="warning" class="mr-4px" @click="handleUpload">上传工具</el-button>
|
||||||
>个筛选结果</div
|
共<span class="color-[#1A65FF]">{{ result?.total }}</span>
|
||||||
>
|
个筛选结果
|
||||||
|
</div>
|
||||||
<div class="content mt-[10px]">
|
<div class="content mt-[10px]">
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col v-for="(item, index) in result?.list" :key="index" :span="6">
|
<el-col v-for="(item, index) in result?.list" :key="index" :span="6">
|
||||||
@ -17,11 +18,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import KlTabBar from '~/components/kl-tab-bar/index.vue'
|
import KlTabBar from '~/components/kl-tab-bar/v3/index.vue'
|
||||||
import CardPicture from '~/components/kl-card-picture/index.vue'
|
import CardPicture from '~/components/kl-card-picture/index.vue'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import type { pageRes, pageReq } from '~/api/upnew/types'
|
import type { pageRes, pageReq } from '~/api/upnew/types'
|
||||||
import emptyImg from '~/assets/images/empty.png'
|
import emptyImg from '~/assets/images/empty.png'
|
||||||
|
import useUserStore from '~/stores/user'
|
||||||
|
|
||||||
const query = defineModel<pageReq>('modelValue', {
|
const query = defineModel<pageReq>('modelValue', {
|
||||||
required: true,
|
required: true,
|
||||||
@ -34,7 +36,7 @@
|
|||||||
const tabBar = ref([
|
const tabBar = ref([
|
||||||
{
|
{
|
||||||
label: '文本推荐',
|
label: '文本推荐',
|
||||||
value: -1
|
value: -1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '原创文本',
|
label: '原创文本',
|
||||||
@ -45,6 +47,15 @@
|
|||||||
value: 2,
|
value: 2,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
|
const handleUpload = () => {
|
||||||
|
// 先判断登录
|
||||||
|
const store = useUserStore()
|
||||||
|
if (!store.token) {
|
||||||
|
return ElMessage.error('请先登录')
|
||||||
|
}
|
||||||
|
navigateTo('/upnew?drawType=2')
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
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
@ -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
@ -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,77 +1,56 @@
|
|||||||
import { isArray } from "~/utils/utils";
|
import { isArray } from '~/utils/utils'
|
||||||
|
import useUserStore from '~/stores/user'
|
||||||
// import refreshToken from "~/utils/RefreshToken";
|
// import refreshToken from "~/utils/RefreshToken";
|
||||||
|
|
||||||
type FetchType = typeof $fetch;
|
type FetchType = typeof $fetch
|
||||||
export type FetchOptions = Parameters<FetchType>[1];
|
export type FetchOptions = Parameters<FetchType>[1]
|
||||||
|
|
||||||
const useClientRequest = async <T = unknown>(
|
const useClientRequest = async <T = unknown>(url: string, opts?: FetchOptions) => {
|
||||||
url: string,
|
const token = useCookie<string | undefined>('token')
|
||||||
opts?: FetchOptions
|
const runtimeConfig = useRuntimeConfig()
|
||||||
) => {
|
const userStore = useUserStore()
|
||||||
const token = useCookie<string | undefined>("token");
|
|
||||||
const runtimeConfig = useRuntimeConfig();
|
|
||||||
|
|
||||||
const defaultOptions: FetchOptions = {
|
const defaultOptions: FetchOptions = {
|
||||||
baseURL: runtimeConfig.public.apiBase,
|
baseURL: runtimeConfig.public.apiBase,
|
||||||
onRequest({ options }) {
|
onRequest({ options }) {
|
||||||
options.headers = options.headers || 'application/json';
|
options.headers = options.headers || 'application/json'
|
||||||
if (token.value) {
|
if (token.value || userStore.token) {
|
||||||
options.headers.set("Authorization", `Bearer ${token.value}`);
|
options.headers.set('Authorization', `Bearer ${token.value || userStore.token}`)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onResponse({ response }) {
|
onResponse({ response }) {
|
||||||
if (+response.status === 200 && +response._data.code !== 0) {
|
if (+response.status === 200 && +response._data.code !== 0) {
|
||||||
ElMessage.error(response._data.msg);
|
ElMessage.error(response._data.msg)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onResponseError({ response }) {
|
onResponseError({ response }) {
|
||||||
ElMessage.error(
|
ElMessage.error(isArray(response._data.data.msg) ? response._data.data.msg[0] : response._data.data.msg)
|
||||||
isArray(response._data.data.msg)
|
|
||||||
? response._data.data.msg[0]
|
|
||||||
: response._data.data.msg
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
};
|
|
||||||
|
|
||||||
// 明确转换返回类型
|
|
||||||
const response = await $fetch(url, { ...defaultOptions, ...opts });
|
|
||||||
return response as unknown as T;
|
|
||||||
};
|
|
||||||
|
|
||||||
// GET请求
|
|
||||||
export const get = <T = unknown>(
|
|
||||||
endpoint: string,
|
|
||||||
config?: Omit<FetchOptions, 'method'>
|
|
||||||
): Promise<T> => {
|
|
||||||
return useClientRequest<T>(endpoint, { ...config, method: 'GET' })
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// POST请求
|
// 明确转换返回类型
|
||||||
export const post = <T = unknown>(
|
const response = await $fetch(url, { ...defaultOptions, ...opts })
|
||||||
endpoint: string,
|
return response as unknown as T
|
||||||
body?: any,
|
}
|
||||||
config?: Omit<FetchOptions, 'method' | 'body'>
|
|
||||||
): Promise<T> => {
|
|
||||||
return useClientRequest<T>(endpoint, { ...config, method: 'POST', body })
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// GET请求
|
||||||
// DELETE请求
|
export const get = <T = unknown>(endpoint: string, config?: Omit<FetchOptions, 'method'>): Promise<T> => {
|
||||||
export const del = <T = unknown>(
|
return useClientRequest<T>(endpoint, { ...config, method: 'GET' })
|
||||||
endpoint: string,
|
}
|
||||||
config?: Omit<FetchOptions, 'method'>
|
|
||||||
): Promise<T> => {
|
|
||||||
return useClientRequest<T>(endpoint, { ...config, method: 'DELETE' })
|
|
||||||
}
|
|
||||||
|
|
||||||
// PUT请求
|
// POST请求
|
||||||
export const put = <T = unknown>(
|
export const post = <T = unknown>(endpoint: string, body?: any, config?: Omit<FetchOptions, 'method' | 'body'>): Promise<T> => {
|
||||||
endpoint: string,
|
return useClientRequest<T>(endpoint, { ...config, method: 'POST', body })
|
||||||
body?: any,
|
}
|
||||||
config?: Omit<FetchOptions, 'method' | 'body'>
|
|
||||||
): Promise<T> => {
|
// DELETE请求
|
||||||
console.log({ ...config, method: 'PUT', body });
|
export const del = <T = unknown>(endpoint: string, config?: Omit<FetchOptions, 'method'>): Promise<T> => {
|
||||||
|
return useClientRequest<T>(endpoint, { ...config, method: 'DELETE' })
|
||||||
return useClientRequest<T>(endpoint, { ...config, method: 'PUT', body })
|
}
|
||||||
}
|
|
||||||
|
// PUT请求
|
||||||
|
export const put = <T = unknown>(endpoint: string, body?: any, config?: Omit<FetchOptions, 'method' | 'body'>): Promise<T> => {
|
||||||
|
console.log({ ...config, method: 'PUT', body })
|
||||||
|
|
||||||
|
return useClientRequest<T>(endpoint, { ...config, method: 'PUT', body })
|
||||||
|
}
|
||||||
|
|||||||
@ -1,17 +1,20 @@
|
|||||||
import { useFetch } from '#app'
|
import { useFetch } from '#app'
|
||||||
import type { UseFetchOptions } from '#app'
|
import type { UseFetchOptions } from '#app'
|
||||||
import { isArray } from '~/utils/utils'
|
import { isArray } from '~/utils/utils'
|
||||||
|
import useUserStore from '~/stores/user'
|
||||||
|
|
||||||
const useServerRequest = async <T>(url: string, opts?: UseFetchOptions<T, unknown>) => {
|
const useServerRequest = async <T>(url: string, opts?: UseFetchOptions<T, unknown>) => {
|
||||||
const token = useToken()
|
const token = useToken()
|
||||||
const runtimeConfig = useRuntimeConfig()
|
const runtimeConfig = useRuntimeConfig()
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
const defaultOptions: UseFetchOptions<unknown> = {
|
const defaultOptions: UseFetchOptions<unknown> = {
|
||||||
baseURL: runtimeConfig.public.apiBase,
|
baseURL: runtimeConfig.public.apiBase,
|
||||||
onRequest({ options }) {
|
onRequest({ options }) {
|
||||||
options.headers = options.headers || {}
|
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 }) {
|
onResponse({ response }) {
|
||||||
|
|||||||
81
composables/useMessage.ts
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import { ElMessage, ElMessageBox, ElNotification } from 'element-plus'
|
||||||
|
export const useMessage = () => {
|
||||||
|
return {
|
||||||
|
// 消息提示
|
||||||
|
info(content: string) {
|
||||||
|
ElMessage.info(content)
|
||||||
|
},
|
||||||
|
// 错误消息
|
||||||
|
error(content: string) {
|
||||||
|
ElMessage.error(content)
|
||||||
|
},
|
||||||
|
// 成功消息
|
||||||
|
success(content: string) {
|
||||||
|
ElMessage.success(content)
|
||||||
|
},
|
||||||
|
// 警告消息
|
||||||
|
warning(content: string) {
|
||||||
|
ElMessage.warning(content)
|
||||||
|
},
|
||||||
|
// 弹出提示
|
||||||
|
alert(content: string, title: string) {
|
||||||
|
ElMessageBox.alert(content, title)
|
||||||
|
},
|
||||||
|
// 错误提示
|
||||||
|
alertError(content: string, title: string) {
|
||||||
|
ElMessageBox.alert(content, title, { type: 'error' })
|
||||||
|
},
|
||||||
|
// 成功提示
|
||||||
|
alertSuccess(content: string, title: string) {
|
||||||
|
ElMessageBox.alert(content, title, { type: 'success' })
|
||||||
|
},
|
||||||
|
// 警告提示
|
||||||
|
alertWarning(content: string, title: string) {
|
||||||
|
ElMessageBox.alert(content, title, { type: 'warning' })
|
||||||
|
},
|
||||||
|
// 通知提示
|
||||||
|
notify(content: string) {
|
||||||
|
ElNotification.info(content)
|
||||||
|
},
|
||||||
|
// 错误通知
|
||||||
|
notifyError(content: string) {
|
||||||
|
ElNotification.error(content)
|
||||||
|
},
|
||||||
|
// 成功通知
|
||||||
|
notifySuccess(content: string) {
|
||||||
|
ElNotification.success(content)
|
||||||
|
},
|
||||||
|
// 警告通知
|
||||||
|
notifyWarning(content: string) {
|
||||||
|
ElNotification.warning(content)
|
||||||
|
},
|
||||||
|
// 确认窗体
|
||||||
|
confirm(content: string, title?: string, options?: any) {
|
||||||
|
return ElMessageBox.confirm(content, title, {
|
||||||
|
type: 'warning',
|
||||||
|
...options
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 删除窗体
|
||||||
|
delConfirm(content?: string, title?: string, options?: any) {
|
||||||
|
return ElMessageBox.confirm(content, title, {
|
||||||
|
type: 'warning',
|
||||||
|
...options
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 导出窗体
|
||||||
|
exportConfirm(content?: string, title?: string, options?: any) {
|
||||||
|
return ElMessageBox.confirm(content, title, {
|
||||||
|
type: 'warning',
|
||||||
|
...options
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 提交内容
|
||||||
|
prompt(content: string, title: string, options?: any) {
|
||||||
|
return ElMessageBox.prompt(content, title, {
|
||||||
|
type: 'warning',
|
||||||
|
...options
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
70
layouts/m.vue
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const active = ref('home')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="m">
|
||||||
|
<div class="scroll-container">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
<!-- 底部信息 -->
|
||||||
|
<div class="footer">
|
||||||
|
<van-tabbar v-model="active">
|
||||||
|
<van-tabbar-item name="home" icon="home-o">标签</van-tabbar-item>
|
||||||
|
<van-tabbar-item name="search" icon="search">标签</van-tabbar-item>
|
||||||
|
<van-tabbar-item name="friends" icon="friends-o">标签</van-tabbar-item>
|
||||||
|
<van-tabbar-item name="setting" icon="setting-o">标签</van-tabbar-item>
|
||||||
|
</van-tabbar>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
/* 移动端样式重置 - 只在移动端布局中生效 */
|
||||||
|
.m {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
.scroll-container {
|
||||||
|
// flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
height: calc(100vh - 40px);
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
/* 重置 body 的最小宽度限制 */
|
||||||
|
:global(body) {
|
||||||
|
min-width: unset !important;
|
||||||
|
width: 100% !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 重置 #__nuxt 容器的样式 */
|
||||||
|
:global(#__nuxt) {
|
||||||
|
min-width: unset !important;
|
||||||
|
width: 100% !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
|
||||||
|
// .page-content {
|
||||||
|
// padding: 0 !important;
|
||||||
|
// overflow-x: hidden !important;
|
||||||
|
|
||||||
|
// .page-table-wrap {
|
||||||
|
// padding: 8px !important;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .page-card {
|
||||||
|
// padding: 8px !important;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 移动端优化滚动条 */
|
||||||
|
:global(::-webkit-scrollbar) {
|
||||||
|
width: 4px !important;
|
||||||
|
height: 4px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
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>
|
||||||
@ -1 +0,0 @@
|
|||||||
// 从微信登录重定向到项目 需要获取code值
|
|
||||||
12
middleware/login.global.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import useUserStore from '~/stores/user'
|
||||||
|
export default defineNuxtRouteMiddleware((to, from) => {
|
||||||
|
const { code, state, type } = to.query
|
||||||
|
if (code && state && type && import.meta.client) {
|
||||||
|
const userStore = useUserStore()
|
||||||
|
userStore.getToken({
|
||||||
|
code: code as string,
|
||||||
|
state: state as string,
|
||||||
|
type: type as string,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
22
middleware/systom.global.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// 区分是手机端还是移动端
|
||||||
|
|
||||||
|
export default defineNuxtRouteMiddleware((to, from) => {
|
||||||
|
if (import.meta.client) {
|
||||||
|
// 在客户端处理路由
|
||||||
|
// 是否是移动端设备
|
||||||
|
const isMobile = /(Android|webOS|iPhone|iPod|tablet|BlackBerry|Mobile)/i.test(navigator.userAgent)
|
||||||
|
// 是否是手机端路由开头
|
||||||
|
const isRouterMobile = to.path.startsWith('/mobile')
|
||||||
|
|
||||||
|
console.log(isMobile, isRouterMobile);
|
||||||
|
|
||||||
|
// 移动端并且 不是/m开头路由
|
||||||
|
if (isMobile && !isRouterMobile) {
|
||||||
|
return navigateTo(`/mobile`)
|
||||||
|
}
|
||||||
|
// 不是移动端 是/m开头路由
|
||||||
|
if (!isMobile && isRouterMobile) {
|
||||||
|
return navigateTo(`/`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
19
middleware/tdk.global.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { getTDKList } from '~/api/home/index'
|
||||||
|
// middleware/tdk.global.ts
|
||||||
|
export default defineNuxtRouteMiddleware(async (to) => {
|
||||||
|
const { data: tdkData } = await getTDKList()
|
||||||
|
// 获取当前路由
|
||||||
|
const currentPath = to.path;
|
||||||
|
// 根据当前路由获取对应的TDK数据
|
||||||
|
const currentTdk = tdkData?.find((item) => item.path === currentPath)
|
||||||
|
|
||||||
|
if (currentTdk) {
|
||||||
|
useHead({
|
||||||
|
title: currentTdk.title,
|
||||||
|
meta: [
|
||||||
|
{ name: 'description', content: currentTdk.describeText },
|
||||||
|
{ name: 'keywords', content: currentTdk.keyword }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
@ -1,5 +1,6 @@
|
|||||||
// import { base_api } from '~/constants/index'
|
// import { base_api } from '~/constants/index'
|
||||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||||
|
import postcsspxtoviewport from 'postcss-px-to-viewport'
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
// devServer: {
|
// devServer: {
|
||||||
// port: 6188,
|
// port: 6188,
|
||||||
@ -11,7 +12,14 @@ export default defineNuxtConfig({
|
|||||||
debug: process.env.NODE_ENV === 'development', // 开启详细调试日志
|
debug: process.env.NODE_ENV === 'development', // 开启详细调试日志
|
||||||
|
|
||||||
ssr: true,
|
ssr: true,
|
||||||
modules: ['@unocss/nuxt', '@pinia/nuxt', '@element-plus/nuxt', 'pinia-plugin-persistedstate/nuxt'],
|
modules: ['@unocss/nuxt', '@pinia/nuxt', '@element-plus/nuxt', 'pinia-plugin-persistedstate/nuxt','@vant/nuxt'],
|
||||||
|
unocss: {
|
||||||
|
nuxtLayers: true,
|
||||||
|
},
|
||||||
|
elementPlus: {
|
||||||
|
importStyle: 'scss', // 或 'css',确保样式被全局导入
|
||||||
|
themes: ['dark'], // 按需配置主题
|
||||||
|
},
|
||||||
css: ['element-plus/dist/index.css', '~/assets/scss/app.scss'],
|
css: ['element-plus/dist/index.css', '~/assets/scss/app.scss'],
|
||||||
vite: {
|
vite: {
|
||||||
css: {
|
css: {
|
||||||
@ -22,17 +30,32 @@ export default defineNuxtConfig({
|
|||||||
},
|
},
|
||||||
postcss: {
|
postcss: {
|
||||||
plugins: [
|
plugins: [
|
||||||
// postCssPxToRem({
|
postcsspxtoviewport({
|
||||||
// rootValue: 16, // 结果为:设计稿元素尺寸/16,比如元素宽320px,最终页面会换算成 20rem
|
unitToConvert: 'px',
|
||||||
// mediaQuery: false, //(布尔值)允许在媒体查询中转换px。
|
viewportWidth: 750,
|
||||||
// // exclude: /node_modules/, //node_modules目录下样式全部不转义
|
unitPrecision: 6,
|
||||||
// propList: ['*'] //需要做转化处理的属性如`hight`、`width`、`margin`等,`*`表示全部
|
propList: ['*'],
|
||||||
// })
|
viewportUnit: 'vw',
|
||||||
|
fontViewportUnit: 'vw',
|
||||||
|
selectorBlackList: ['el-'],
|
||||||
|
minPixelValue: 1,
|
||||||
|
mediaQuery: true,
|
||||||
|
replace: true,
|
||||||
|
// 严格只允许 pages/mobile 下的文件被转换
|
||||||
|
// 使用强排除:排除 node_modules 和 所有不在 pages/mobile 下的文件
|
||||||
|
exclude: [
|
||||||
|
/node_modules/,
|
||||||
|
/^(?!.*\/(pages|src)\/mobile\/).*$/
|
||||||
|
],
|
||||||
|
landscape: false,
|
||||||
|
// 可选:进一步放宽 include,以便某些移动端专用布局文件也参与
|
||||||
|
include: [/\/pages\/mobile\//],
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
include: ['naive-ui'],
|
include: ['element-plus','unocss'], // 预构建依赖项
|
||||||
},
|
},
|
||||||
// 生产环境构建优化
|
// 生产环境构建优化
|
||||||
build: {
|
build: {
|
||||||
@ -73,20 +96,20 @@ export default defineNuxtConfig({
|
|||||||
{ name: 'keywords', content: '图纸,图纸下载,设计素材,图纸大全,设计图纸,,工程图纸,cad图纸' },
|
{ name: 'keywords', content: '图纸,图纸下载,设计素材,图纸大全,设计图纸,,工程图纸,cad图纸' },
|
||||||
{ name: 'author', content: '图夕夕' },
|
{ name: 'author', content: '图夕夕' },
|
||||||
// SEO meta tags
|
// SEO meta tags
|
||||||
{
|
// {
|
||||||
property: 'og:title',
|
// property: 'og:title',
|
||||||
content: '图纸,图纸下载,设计素材,图纸大全,设计图纸,,工程图纸,cad图纸',
|
// content: '图纸,图纸下载,设计素材,图纸大全,设计图纸,,工程图纸,cad图纸',
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
property: 'og:description',
|
// property: 'og:description',
|
||||||
content: '图夕夕是一家图纸素材分享交易平台,提供AutoCAD/ProE/Creo/CATIA/UG/inventor/CAXA/等建筑图纸的素材下载及免费教程。',
|
// content: '图夕夕是一家图纸素材分享交易平台,提供AutoCAD/ProE/Creo/CATIA/UG/inventor/CAXA/等建筑图纸的素材下载及免费教程。',
|
||||||
},
|
// },
|
||||||
{ property: 'og:type', content: 'website' },
|
// { property: 'og:type', content: 'website' },
|
||||||
{ property: 'og:url', content: 'https://www.xlcig.cn' },
|
// { property: 'og:url', content: 'https://www.xlcig.cn' },
|
||||||
{ property: 'og:site_name', content: 'xlCig' },
|
// { property: 'og:site_name', content: 'xlCig' },
|
||||||
{ name: 'theme-color', content: '#00f5ff' },
|
// { name: 'theme-color', content: '#00f5ff' },
|
||||||
// robots meta
|
// // robots meta
|
||||||
{ name: 'robots', content: 'index, follow' },
|
// { name: 'robots', content: 'index, follow' },
|
||||||
],
|
],
|
||||||
link: [
|
link: [
|
||||||
{ rel: 'icon', type: 'image/x-icon', href: '/favicon2.ico' },
|
{ rel: 'icon', type: 'image/x-icon', href: '/favicon2.ico' },
|
||||||
@ -119,7 +142,7 @@ export default defineNuxtConfig({
|
|||||||
},
|
},
|
||||||
|
|
||||||
build: {
|
build: {
|
||||||
transpile: ['vueuc', '@css-render/vue3-ssr', '@tinymce/tinymce-vue', 'tinymce'],
|
transpile: process.env.NODE_ENV === 'production' ? ['lodash'] : [],
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
// 在这里引入插件
|
// 在这里引入插件
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "nuxt-app",
|
"name": "nuxt-app",
|
||||||
|
"version": "1.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@ -16,11 +17,14 @@
|
|||||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||||
"decimal.js": "^10.6.0",
|
"decimal.js": "^10.6.0",
|
||||||
"echarts": "^6.0.0",
|
"echarts": "^6.0.0",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
"mqtt": "^5.14.0",
|
"mqtt": "^5.14.0",
|
||||||
"nuxt": "^3.18.1",
|
"nuxt": "^3.18.1",
|
||||||
"pdfjs-dist": "^5.4.54",
|
"pdfjs-dist": "^5.4.54",
|
||||||
"pinia": "^3.0.3",
|
"pinia": "^3.0.3",
|
||||||
|
"postcss-px-to-viewport": "^1.1.1",
|
||||||
"qrcode.vue": "^3.6.0",
|
"qrcode.vue": "^3.6.0",
|
||||||
|
"vant": "^4.9.21",
|
||||||
"vue": "^3.5.18",
|
"vue": "^3.5.18",
|
||||||
"vue-pdf-embed": "^2.1.3",
|
"vue-pdf-embed": "^2.1.3",
|
||||||
"vue-router": "^4.5.1",
|
"vue-router": "^4.5.1",
|
||||||
@ -32,7 +36,9 @@
|
|||||||
"@pinia-plugin-persistedstate/nuxt": "^1.2.1",
|
"@pinia-plugin-persistedstate/nuxt": "^1.2.1",
|
||||||
"@types/prettier": "^3.0.0",
|
"@types/prettier": "^3.0.0",
|
||||||
"@unocss/nuxt": "^66.4.2",
|
"@unocss/nuxt": "^66.4.2",
|
||||||
|
"@vant/nuxt": "^1.0.7",
|
||||||
"element-plus": "^2.10.7",
|
"element-plus": "^2.10.7",
|
||||||
|
"postcss": "^8.5.6",
|
||||||
"prettier": "3.6.2",
|
"prettier": "3.6.2",
|
||||||
"sass": "^1.90.0",
|
"sass": "^1.90.0",
|
||||||
"unocss": "^66.4.2"
|
"unocss": "^66.4.2"
|
||||||
|
|||||||
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>
|
||||||
@ -2,6 +2,7 @@
|
|||||||
<div class="ml-[19px] w-[100%]">
|
<div class="ml-[19px] w-[100%]">
|
||||||
<ChannelHeader v-if="Object.keys(lunTanRes || {}).length" v-model="lunTanRes"></ChannelHeader>
|
<ChannelHeader v-if="Object.keys(lunTanRes || {}).length" v-model="lunTanRes"></ChannelHeader>
|
||||||
<div
|
<div
|
||||||
|
v-if="pageRes?.list.length"
|
||||||
class="mb-[13px] box-border flex flex-1 flex-col cursor-pointer gap-[12px] border border-[#EEEEEE] rounded-[8px] border-solid bg-[#FFFFFF] px-[20px] py-[16px]"
|
class="mb-[13px] box-border flex flex-1 flex-col cursor-pointer gap-[12px] border border-[#EEEEEE] rounded-[8px] border-solid bg-[#FFFFFF] px-[20px] py-[16px]"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -20,7 +21,7 @@
|
|||||||
<div class="w-[100px] flex flex-shrink-0 items-center justify-end">
|
<div class="w-[100px] flex flex-shrink-0 items-center justify-end">
|
||||||
<span class="ellipsis text-[13px] color-[#96999f]">{{ item.creatorName }}</span>
|
<span class="ellipsis text-[13px] color-[#96999f]">{{ item.creatorName }}</span>
|
||||||
<!-- 删除 -->
|
<!-- 删除 -->
|
||||||
<el-button v-if="false" type="danger" size="small" @click="handleDelete(item.postsId)">删除</el-button>
|
<el-button v-if="false" type="danger" size="small" @click.stop="handleDelete(item.postsId)">删除</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -13,15 +13,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="mt-[19px] flex items-center justify-between">
|
<div class="mt-[19px] flex items-center justify-between">
|
||||||
<div class="flex items-center">
|
<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>
|
<span class="text-[#666666]">{{ channelDetail?.likeNum || 0 }}人赞过</span>
|
||||||
<div class="ml-[16px] flex items-center">
|
<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>
|
<span class="text-[#666666]">{{ channelDetail?.commentNum || 0 }}评论</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-[16px] flex items-center">
|
<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>
|
<span class="text-[#666666]">{{ channelDetail?.browseNum || 0 }}人看过</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -104,7 +104,6 @@
|
|||||||
const channelId = computed(() => route.params.channelId as string)
|
const channelId = computed(() => route.params.channelId as string)
|
||||||
const pageNo = computed(() => Number(route.params.pageNo))
|
const pageNo = computed(() => Number(route.params.pageNo))
|
||||||
|
|
||||||
console.log(channelId.value, pageNo.value)
|
|
||||||
|
|
||||||
// const channelDetail = ref<TGetChannelPostsRes>()
|
// const channelDetail = ref<TGetChannelPostsRes>()
|
||||||
// const commentList = reactive<PageResultPostsCommentRespVO>({
|
// const commentList = reactive<PageResultPostsCommentRespVO>({
|
||||||
|
|||||||
@ -1,18 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<SeoHead :title="detail?.title" :description="detail?.description" :keywords="detail?.labels?.toString()" />
|
||||||
<KlNavTab />
|
<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="ml-auto mr-auto mt-[20px] w-[1440px]">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div
|
<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]"
|
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">
|
<div class="flex items-center">
|
||||||
<img :src="detail?.ownedUserIdInfo?.avatar" alt="" srcset="" class="h-[30px] w-[30px] rd-[50%]" />
|
<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>
|
<span class="ml-[12px] color-[#999999]">by {{ detail?.ownedUserIdInfo?.nickName }}</span>
|
||||||
</div>
|
</div>
|
||||||
</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">
|
<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]" />
|
<img src="~/assets/images/download.png" alt="" srcset="" class="mr-[4px] h-[22px] w-[27px]" />
|
||||||
{{ detail?.points === 0 ? '免费下载' : '立即下载' }}
|
{{ detail?.points === 0 ? '免费下载' : '立即下载' }}
|
||||||
@ -39,26 +45,31 @@
|
|||||||
<div>
|
<div>
|
||||||
<ThumBnail :data="detail?.coverImages" :type="detail?.type"></ThumBnail>
|
<ThumBnail :data="detail?.coverImages" :type="detail?.type"></ThumBnail>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-[20px] mt-[34px] flex items-center text-[16px] text-[#333333] font-normal">
|
<div class="mb-[20px] mt-[34px] flex items-center text-[14px] 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="h-[20px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div><span class="ml-[10px]">{{ detail?.title }}描述</span></div
|
||||||
>
|
>
|
||||||
<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"
|
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 }}
|
{{ detail?.description }}
|
||||||
</div>
|
</div>
|
||||||
<div id="section1" class="mb-[20px] mt-[34px] flex items-center text-[16px] text-[#333333] font-normal">
|
<div id="section1" class="mb-[20px] mt-[34px] flex items-center text-[14px] 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="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="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 class="border-b-[1px] border-b-[#eee] border-b-solid p-b-[10px]">
|
||||||
{{ detail?.type === 1 ? '图纸' : detail?.type === 2 ? '文本' : '模型' }}中包含的文件
|
{{ detail?.type === 1 ? '图纸' : detail?.type === 2 ? '文本' : '模型' }}中包含的文件
|
||||||
</div>
|
</div>
|
||||||
<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]">
|
<div
|
||||||
|
v-for="item in detail?.otherFiles"
|
||||||
|
: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" /> -->
|
<!-- <img src="~/assets/images/avater.png" alt="" srcset="" class="h-30px w-30px" /> -->
|
||||||
<div>
|
<div>
|
||||||
<span class="ml-[10px] cursor-pointer" @click="handleDownloadPreview(item)">{{ item.title }}</span>
|
<!-- <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>
|
<span v-if="item.size" class="ml-[200px] color-[#999]">{{ item.size || '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<el-button
|
<el-button
|
||||||
@ -75,8 +86,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 关联项目 -->
|
<!-- 关联项目 -->
|
||||||
<div class="mb-[20px] mt-[34px] flex items-center text-[16px] text-[#333333] font-normal">
|
<div class="mb-[20px] mt-[34px] flex items-center text-[14px] text-[#333333] font-normal">
|
||||||
<div class="h-[24px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div
|
<div class="h-[20px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div
|
||||||
><span class="ml-[10px]">关联{{ detail?.type === 1 ? '图纸' : detail?.type === 2 ? '文本' : '模型' }}</span></div
|
><span class="ml-[10px]">关联{{ detail?.type === 1 ? '图纸' : detail?.type === 2 ? '文本' : '模型' }}</span></div
|
||||||
>
|
>
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
@ -86,8 +97,8 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
<el-empty v-if="!detail?.relationDraws?.length" description="暂无数据"></el-empty>
|
<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="mb-[20px] mt-[34px] flex items-center text-[14px] text-[#333333] font-normal">
|
||||||
<div class="h-[24px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div
|
<div class="h-[20px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div
|
||||||
><span class="ml-[10px]">相关{{ detail?.type === 1 ? '图纸' : detail?.type === 2 ? '文本' : '模型' }}推荐</span></div
|
><span class="ml-[10px]">相关{{ detail?.type === 1 ? '图纸' : detail?.type === 2 ? '文本' : '模型' }}推荐</span></div
|
||||||
>
|
>
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
@ -100,7 +111,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="ml-[22px]">
|
<div class="ml-[22px]">
|
||||||
<div class="box-border min-h-[269px] w-[397px] border border-[#EEEEEE] rounded-[12px] border-solid bg-[#FFFFFF] pa-[22px]">
|
<div class="box-border min-h-[269px] w-[397px] border border-[#EEEEEE] rounded-[12px] border-solid bg-[#FFFFFF] pa-[22px]">
|
||||||
<div class="mb-[10px]">图纸ID: {{ detail?.id }}</div>
|
<div class="mb-[10px]">图纸ID: {{ detail?.no }}</div>
|
||||||
<div class="mb-[10px]">文件大小:{{ detail?.filesInfo?.fileSize || 0 }} </div>
|
<div class="mb-[10px]">文件大小:{{ detail?.filesInfo?.fileSize || 0 }} </div>
|
||||||
<!-- <div class="mb-10px">图纸版本:{{ detail.editionsName }} </div> -->
|
<!-- <div class="mb-10px">图纸版本:{{ detail.editionsName }} </div> -->
|
||||||
<div class="mb-[10px]">图纸格式:{{ detail?.formatType?.toString() }}</div>
|
<div class="mb-[10px]">图纸格式:{{ detail?.formatType?.toString() }}</div>
|
||||||
@ -135,7 +146,7 @@
|
|||||||
<div class="h-[20px]">
|
<div class="h-[20px]">
|
||||||
<img src="~/assets/images/user4.png" alt="fans" class="w-[80%] rounded-full vertical-top" />
|
<img src="~/assets/images/user4.png" alt="fans" class="w-[80%] rounded-full vertical-top" />
|
||||||
</div>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -152,8 +163,8 @@
|
|||||||
|
|
||||||
<div class="mt-[20px] h-[1px] w-[336px] rounded-[1px] bg-[#EEEEEE]"></div>
|
<div class="mt-[20px] h-[1px] w-[336px] rounded-[1px] bg-[#EEEEEE]"></div>
|
||||||
<div class="mt-[20px] flex items-center">
|
<div class="mt-[20px] flex items-center">
|
||||||
<div class="h-[24px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div>
|
<div class="h-[20px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div>
|
||||||
<span class="ml-[10px] text-[16px]">最新发布</span>
|
<span class="ml-[10px] text-[14px]">最新发布</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-[10px]">
|
<div class="mt-[10px]">
|
||||||
<div
|
<div
|
||||||
@ -174,10 +185,13 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
|
import { ArrowRight } from '@element-plus/icons-vue'
|
||||||
import { downloadFile } from '~/utils/utils'
|
import { downloadFile } from '~/utils/utils'
|
||||||
import { useMessage } from '~/utils/useMessage'
|
import { useMessage } from '~/utils/useMessage'
|
||||||
import { Warning } from '@element-plus/icons-vue'
|
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 CardPicture from '~/components/kl-card-picture/index.vue'
|
||||||
|
import { getDictTree } from '~/api/home/index'
|
||||||
import { getDetail, getRelationRecommend, report, getUserInfo, getMainWork, createContent, createUserProject, deleteProject } from '~/api/drawe-detail/index'
|
import { getDetail, getRelationRecommend, report, getUserInfo, getMainWork, createContent, createUserProject, deleteProject } from '~/api/drawe-detail/index'
|
||||||
import KlNavTab from '~/components/kl-nav-tab/index.vue'
|
import KlNavTab from '~/components/kl-nav-tab/index.vue'
|
||||||
import ThumBnail from './components/swiper.vue'
|
import ThumBnail from './components/swiper.vue'
|
||||||
@ -210,6 +224,20 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取面包屑
|
||||||
|
const { data: breadList } = await useAsyncData(`breadList-detail-${route.params.id}}`, async () => {
|
||||||
|
const res = await getDictTree({ type: 1, id: detail.value?.projectType?.[0] })
|
||||||
|
const all = [
|
||||||
|
{
|
||||||
|
id: -1,
|
||||||
|
name: detail.value?.type === 1 ? '图纸库' : detail.value?.type === 3 ? '模型库' : '文本库',
|
||||||
|
isChildren: false,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const arr = [...res.data, ...all]
|
||||||
|
return arr.reverse()
|
||||||
|
})
|
||||||
|
|
||||||
// const init = () => {
|
// const init = () => {
|
||||||
// getDetail({ id }).then((res) => {
|
// getDetail({ id }).then((res) => {
|
||||||
// if (res.code === 0) {
|
// if (res.code === 0) {
|
||||||
@ -333,6 +361,7 @@
|
|||||||
comments: value,
|
comments: value,
|
||||||
projectId: detail.value?.projectId,
|
projectId: detail.value?.projectId,
|
||||||
drawId: detail.value?.id,
|
drawId: detail.value?.id,
|
||||||
|
type: detail.value?.type,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
ElMessage.success('举报成功')
|
ElMessage.success('举报成功')
|
||||||
@ -352,6 +381,7 @@
|
|||||||
: await createContent({
|
: await createContent({
|
||||||
projectId: detail.value?.projectId,
|
projectId: detail.value?.projectId,
|
||||||
drawId: detail.value?.id,
|
drawId: detail.value?.id,
|
||||||
|
type: detail.value?.type,
|
||||||
})
|
})
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
ElMessage.success(`${detail.value?.favoriteId ? '取消' : '收藏'}成功`)
|
ElMessage.success(`${detail.value?.favoriteId ? '取消' : '收藏'}成功`)
|
||||||
|
|||||||
@ -10,8 +10,8 @@
|
|||||||
<div class="swiper-button-prev"></div>
|
<div class="swiper-button-prev"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-[20px] mt-[34px] flex items-center text-[16px] text-[#333333] font-normal">
|
<div class="mb-[20px] mt-[34px] flex items-center text-[14px] text-[#333333] font-normal">
|
||||||
<div class="h-[24px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div>
|
<div class="h-[20px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div>
|
||||||
<span class="ml-[10px]">{{ props.type === 1 ? '图纸' : props.type === 2 ? '文本' : '模型' }}</span>
|
<span class="ml-[10px]">{{ props.type === 1 ? '图纸' : props.type === 2 ? '文本' : '模型' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-border h-[126px] w-[1019px] border border-[#EEEEEE] rounded-[6px] border-solid bg-[#FFFFFF] pa-[23px]">
|
<div class="box-border h-[126px] w-[1019px] border border-[#EEEEEE] rounded-[6px] border-solid bg-[#FFFFFF] pa-[23px]">
|
||||||
|
|||||||
@ -62,6 +62,7 @@
|
|||||||
source: source.value || -1,
|
source: source.value || -1,
|
||||||
type: 1,
|
type: 1,
|
||||||
title: keywords.value,
|
title: keywords.value,
|
||||||
|
recommend: source.value === -1 ? true : false,
|
||||||
})
|
})
|
||||||
// const result = reactive<pageRes>({
|
// const result = reactive<pageRes>({
|
||||||
// list: [],
|
// list: [],
|
||||||
@ -93,6 +94,7 @@
|
|||||||
editions: query.value.editions === '-1' ? '' : query.value.editions,
|
editions: query.value.editions === '-1' ? '' : query.value.editions,
|
||||||
source: query.value.source === -1 ? '' : query.value.source,
|
source: query.value.source === -1 ? '' : query.value.source,
|
||||||
projectType: query.value.projectType === '-1' ? '' : query.value.projectType,
|
projectType: query.value.projectType === '-1' ? '' : query.value.projectType,
|
||||||
|
recommend: query.value.source === -1 ? true: false,
|
||||||
})
|
})
|
||||||
return res.data
|
return res.data
|
||||||
},
|
},
|
||||||
|
|||||||
@ -55,6 +55,7 @@
|
|||||||
source: -1,
|
source: -1,
|
||||||
type: 1,
|
type: 1,
|
||||||
title: keywords.value,
|
title: keywords.value,
|
||||||
|
recommend: true,
|
||||||
})
|
})
|
||||||
// const result = reactive<pageRes>({
|
// const result = reactive<pageRes>({
|
||||||
// list: [],
|
// list: [],
|
||||||
@ -79,13 +80,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { data: result, refresh: getPage } = useAsyncData(
|
const { data: result, refresh: getPage } = useAsyncData(
|
||||||
`draw-page-list-${query.value.projectType}-${query.value.editions}-${query.value.source}-${query.value.pageNo}-${query.value.pageSize}-${query.value.title}`,
|
`draw-page-list-drawe-${query.value.projectType}-${query.value.editions}-${query.value.source}-${query.value.pageNo}-${query.value.pageSize}-${query.value.title}`,
|
||||||
async () => {
|
async () => {
|
||||||
const res = await page({
|
const res = await page({
|
||||||
...query.value,
|
...query.value,
|
||||||
editions: query.value.editions === '-1' ? '' : query.value.editions,
|
editions: query.value.editions === '-1' ? '' : query.value.editions,
|
||||||
source: query.value.source === -1 ? '' : query.value.source,
|
source: query.value.source === -1 ? '' : query.value.source,
|
||||||
projectType: query.value.projectType === '-1' ? '' : query.value.projectType,
|
projectType: query.value.projectType === '-1' ? '' : query.value.projectType,
|
||||||
|
recommend: query.value.source === -1 ? true: false,
|
||||||
})
|
})
|
||||||
return res.data
|
return res.data
|
||||||
},
|
},
|
||||||
|
|||||||
@ -0,0 +1,127 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 导航 -->
|
||||||
|
<KlNavTab active="国外专区" />
|
||||||
|
<!-- banneer提示 -->
|
||||||
|
<BannerTips />
|
||||||
|
<div class="ma-auto w-[1440px]">
|
||||||
|
<!-- 图片展示鼠标移上去展示提示语 -->
|
||||||
|
<!-- <ImageTips /> -->
|
||||||
|
<!-- 推荐栏目 -->
|
||||||
|
<RecommendedColumnsV2 v-model:query="query" v-model="result"></RecommendedColumnsV2>
|
||||||
|
<!-- 精选专题 -->
|
||||||
|
<!-- <FeaturedSpecials></FeaturedSpecials> -->
|
||||||
|
<!-- 分页 -->
|
||||||
|
<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="handleChangeSize"
|
||||||
|
@current-change="handleChangeCurrent"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import KlNavTab from '~/components/kl-nav-tab/index.vue'
|
||||||
|
import RecommendedColumnsV2 from '~/components/foreign-components/RecommendedColumnsV2.vue'
|
||||||
|
import BannerTips from '~/components/foreign-components/BannerTips.vue'
|
||||||
|
// import FeaturedSpecials from './components/FeaturedSpecials.vue'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { reactive, watch, ref } from 'vue'
|
||||||
|
import { page } from '~/api/upnew/index'
|
||||||
|
import { getDictTree } from '~/api/home/index'
|
||||||
|
import type { pageRes, pageReq } from '~/api/upnew/types'
|
||||||
|
const route = useRoute()
|
||||||
|
const projectType = computed(() => (route.params?.projectType ? route.params?.projectType : ''))
|
||||||
|
const pageNo = computed(() => Number(route.params?.pageNo))
|
||||||
|
const pageSize = computed(() => Number(route.params?.pageSize))
|
||||||
|
const editions = computed(() => (route.params?.editions ? route.params?.editions : ''))
|
||||||
|
const source = computed(() => (route.params?.source ? Number(route.params?.source) : ''))
|
||||||
|
|
||||||
|
console.log('route.params----', route.params)
|
||||||
|
|
||||||
|
const level = ref(
|
||||||
|
route.query?.valuelevel
|
||||||
|
? JSON.parse(route.query.valuelevel as string)
|
||||||
|
: [
|
||||||
|
{
|
||||||
|
id: -1,
|
||||||
|
name: '图纸库',
|
||||||
|
isChildren: false,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
)
|
||||||
|
const keywords = ref((route.query?.valuekeywords as string) || '')
|
||||||
|
|
||||||
|
const query = ref<pageReq>({
|
||||||
|
pageNo: pageNo.value || 1,
|
||||||
|
pageSize: pageSize.value || 12,
|
||||||
|
projectType: projectType.value || '-1',
|
||||||
|
editions: editions.value || '-1',
|
||||||
|
source: source.value || -1,
|
||||||
|
type: 1,
|
||||||
|
title: keywords.value,
|
||||||
|
})
|
||||||
|
// const result = reactive<pageRes>({
|
||||||
|
// list: [],
|
||||||
|
// total: 0,
|
||||||
|
// })
|
||||||
|
|
||||||
|
// 如果id存在,则设置projectType
|
||||||
|
if (level.value.length) {
|
||||||
|
// query.value.projectType = level.value[level.value.length - 1].id || ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChangeSize = (val: number) => {
|
||||||
|
query.value.pageSize = val
|
||||||
|
// getPage()
|
||||||
|
navigateTo(`/foreign/${query.value.projectType}/${query.value.pageNo}/${val}/${query.value.editions}/${query.value.source}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChangeCurrent = (val: number) => {
|
||||||
|
query.value.pageNo = val
|
||||||
|
// getPage()
|
||||||
|
navigateTo(`/foreign/${query.value.projectType}/${val}/${query.value.pageSize}/${query.value.editions}/${query.value.source}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data: result, refresh: getPage } = useAsyncData(
|
||||||
|
`foreign-page-list-${query.value.projectType}-${query.value.editions}-${query.value.source}-${query.value.pageNo}-${query.value.pageSize}-${query.value.title}`,
|
||||||
|
async () => {
|
||||||
|
const res = await page({
|
||||||
|
...query.value,
|
||||||
|
editions: query.value.editions === '-1' ? '' : query.value.editions,
|
||||||
|
source: query.value.source === -1 ? '' : query.value.source,
|
||||||
|
projectType: query.value.projectType === '-1' ? '' : query.value.projectType,
|
||||||
|
})
|
||||||
|
return res.data
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// const getPage = () => {
|
||||||
|
// page(query).then((res) => {
|
||||||
|
// const { data, code } = res
|
||||||
|
// if (code === 0) {
|
||||||
|
// result.list = data.list
|
||||||
|
// result.total = data.total
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
watch([() => query.value.projectType, () => query.value.editions, () => query.value.source], (val) => {
|
||||||
|
if (val) {
|
||||||
|
navigateTo(`/foreign/${query.value.projectType}/1/${query.value.pageSize}/${query.value.editions}/${query.value.source}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
:deep(.el-pagination) {
|
||||||
|
.el-input__inner {
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -26,30 +26,41 @@
|
|||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import KlNavTab from '~/components/kl-nav-tab/index.vue'
|
import KlNavTab from '~/components/kl-nav-tab/index.vue'
|
||||||
import RecommendedColumnsV2 from './components/RecommendedColumnsV2.vue'
|
import RecommendedColumnsV2 from '~/components/foreign-components/RecommendedColumnsV2.vue'
|
||||||
// import FeaturedSpecials from './components/FeaturedSpecials.vue'
|
// import FeaturedSpecials from './components/FeaturedSpecials.vue'
|
||||||
import BannerTips from './components/BannerTips.vue'
|
import BannerTips from '~/components/foreign-components/BannerTips.vue'
|
||||||
// import ImageTips from './components/ImageTips.vue'
|
// import ImageTips from './components/ImageTips.vue'
|
||||||
|
|
||||||
import { reactive, watch } from 'vue'
|
import { reactive, watch } from 'vue'
|
||||||
import { page } from '~/api/upnew/index'
|
import { page } from '~/api/upnew/index'
|
||||||
import type { pageRes, pageReq } from '~/api/upnew/types'
|
import type { pageRes, pageReq } from '~/api/upnew/types'
|
||||||
|
|
||||||
const query = reactive<pageReq>({
|
const query = reactive<
|
||||||
|
pageReq & {
|
||||||
|
isDomestic: number
|
||||||
|
}
|
||||||
|
>({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
projectType: '',
|
projectType: '-1',
|
||||||
editions: '',
|
editions: '-1',
|
||||||
source: '',
|
source: -1,
|
||||||
type: 1,
|
type: 1,
|
||||||
|
/**是否是国内: 1是 0否 */
|
||||||
|
isDomestic: 1,
|
||||||
})
|
})
|
||||||
// const result = reactive<pageRes>({
|
// const result = reactive<pageRes>({
|
||||||
// list: [],
|
// list: [],
|
||||||
// total: 0,
|
// total: 0,
|
||||||
// })
|
// })
|
||||||
|
|
||||||
const {data:result, refresh:getPage } = await useAsyncData(`draw-page-list-${Date.now()}`, async () => {
|
const { data: result } = await useAsyncData(`draw-page-list-${Date.now()}`, async () => {
|
||||||
const res = await page(query)
|
const res = await page({
|
||||||
|
...query,
|
||||||
|
editions: query.editions === '-1' ? '' : query.editions,
|
||||||
|
source: query.source === -1 ? '' : query.source,
|
||||||
|
projectType: query.projectType === '-1' ? '' : query.projectType,
|
||||||
|
})
|
||||||
return res.data
|
return res.data
|
||||||
})
|
})
|
||||||
// const getPage = () => {
|
// const getPage = () => {
|
||||||
@ -66,18 +77,23 @@
|
|||||||
|
|
||||||
const handleChangeSize = (val: number) => {
|
const handleChangeSize = (val: number) => {
|
||||||
query.pageSize = val
|
query.pageSize = val
|
||||||
query.pageNo = 1
|
// query.pageNo = 1
|
||||||
getPage()
|
// getPage()
|
||||||
|
|
||||||
|
navigateTo(`/foreign/${query.projectType}/${query.pageNo}/${val}/${query.editions}/${query.source}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleChangeCurrent = (val: number) => {
|
const handleChangeCurrent = (val: number) => {
|
||||||
query.pageNo = val
|
query.pageNo = val
|
||||||
getPage()
|
// getPage()
|
||||||
|
navigateTo(`/foreign/${query.projectType}/${val}/${query.pageSize}/${query.editions}/${query.source}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
watch([() => query.projectType, () => query.editions, () => query.source], (val) => {
|
watch([() => query.projectType, () => query.editions, () => query.source], (val) => {
|
||||||
if (val) {
|
if (val) {
|
||||||
getPage()
|
// getPage()
|
||||||
|
|
||||||
|
navigateTo(`/foreign/${query.projectType}/1/${query.pageSize}/${query.editions}/${query.source}`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -79,7 +79,7 @@
|
|||||||
<div class="text-[15px] color-[#999]">{{ dayjs(item.createTime).format('MM-DD') }}</div>
|
<div class="text-[15px] color-[#999]">{{ dayjs(item.createTime).format('MM-DD') }}</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 暂无数据 -->
|
<!-- 暂无数据 -->
|
||||||
<el-empty v-if="!newDrawList.length" description="暂无数据"></el-empty>
|
<el-empty v-if="!newDrawList?.length" description="暂无数据"></el-empty>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<div class="login-container flex flex-col justify-between">
|
<div class="login-container flex flex-col justify-between">
|
||||||
<div class="ma-auto mt-[25px] w-[100%] flex flex-col items-center">
|
<div class="ma-auto mt-[25px] w-[100%] flex flex-col items-center">
|
||||||
<el-image
|
<el-image
|
||||||
:src="userStore.userInfoRes.avatar || 'https://tuxixi.oss-cn-chengdu.aliyuncs.com/avater.png'"
|
:src="userStore.userInfoRes.avatar || 'https://static.tuxixi.net/1757297277142/2025/09/08/10/07/57/tuxixi.png'"
|
||||||
alt=""
|
alt=""
|
||||||
srcset=""
|
srcset=""
|
||||||
class="h-[69px] w-[69px] rd-[50%]"
|
class="h-[69px] w-[69px] rd-[50%]"
|
||||||
@ -11,7 +11,7 @@
|
|||||||
@click="handleUserInfo"
|
@click="handleUserInfo"
|
||||||
/>
|
/>
|
||||||
<div class="mt-[10px] text-[16px] text-[#333333] font-normal flex items-center">
|
<div class="mt-[10px] text-[16px] text-[#333333] font-normal flex items-center">
|
||||||
Hi,{{ userStore.userInfoRes.nickname || '欢迎访问~' }}
|
Hi,{{ userStore.userInfoRes.nickname || '欢迎访问图夕夕' }}
|
||||||
<img v-if="userStore.userInfoRes.vipLevel === 1" src="~/assets/svg/vip.svg" alt="" class="relative top-[1px]" />
|
<img v-if="userStore.userInfoRes.vipLevel === 1" src="~/assets/svg/vip.svg" alt="" class="relative top-[1px]" />
|
||||||
<img v-if="userStore.userInfoRes.vipLevel === 2" src="~/assets/svg/svip.svg" alt="" class="relative top-[1px]" />
|
<img v-if="userStore.userInfoRes.vipLevel === 2" src="~/assets/svg/svip.svg" alt="" class="relative top-[1px]" />
|
||||||
</div>
|
</div>
|
||||||
@ -38,7 +38,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!isLogin" class="mt-[48px] box-border flex justify-between px-[18px]">
|
<div v-if="!isLogin" class="mt-[46px] box-border flex justify-between px-[18px]">
|
||||||
<div
|
<div
|
||||||
class="h-[37px] w-[101px] cursor-pointer border border-[#1A65FF] rounded-[2px] border-solid bg-[#1A65FF] text-center text-[14px] text-[#FFFFFF] font-normal line-height-[37px]"
|
class="h-[37px] w-[101px] cursor-pointer border border-[#1A65FF] rounded-[2px] border-solid bg-[#1A65FF] text-center text-[14px] text-[#FFFFFF] font-normal line-height-[37px]"
|
||||||
@click="handleLogin"
|
@click="handleLogin"
|
||||||
@ -50,7 +50,7 @@
|
|||||||
>免费注册</div
|
>免费注册</div
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="mt-[30px] box-border flex justify-between px-[18px]">
|
<div v-else class="mt-[24px] box-border flex justify-between px-[18px]">
|
||||||
<div
|
<div
|
||||||
class="h-[37px] w-[101px] cursor-pointer border border-[#1A65FF] rounded-[2px] border-solid bg-[#1A65FF] text-center text-[14px] text-[#FFFFFF] font-normal line-height-[37px]"
|
class="h-[37px] w-[101px] cursor-pointer border border-[#1A65FF] rounded-[2px] border-solid bg-[#1A65FF] text-center text-[14px] text-[#FFFFFF] font-normal line-height-[37px]"
|
||||||
@click="handleDrawe"
|
@click="handleDrawe"
|
||||||
@ -64,7 +64,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="!isLogin" class="mt-[30px] flex justify-between px-[20px]">
|
<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/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/email-v2.png" alt="邮箱登录" class="social-icon" @click="handleLoginEmail" />
|
||||||
<img src="~/assets/images/phone-v2.png" alt="手机登录" class="social-icon" @click="handleLoginPhone" />
|
<img src="~/assets/images/phone-v2.png" alt="手机登录" class="social-icon" @click="handleLoginPhone" />
|
||||||
</div>
|
</div>
|
||||||
@ -73,6 +73,9 @@
|
|||||||
<img src="~/assets/images/sign.png" alt="签到奖励" class="bonus-image" />
|
<img src="~/assets/images/sign.png" alt="签到奖励" class="bonus-image" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- wx二维码弹窗 -->
|
||||||
|
<wx v-model:visible="visible" v-if="visible" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@ -90,6 +93,12 @@
|
|||||||
return !!userStore.token
|
return !!userStore.token
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 打开微信二维码
|
||||||
|
const visible = ref<boolean>(false)
|
||||||
|
const handleLoginWechatV2 = () => {
|
||||||
|
visible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
// 获取用户统计信息
|
// 获取用户统计信息
|
||||||
const userStaticInfo = ref<UserStatisticsCountRespVO>()
|
const userStaticInfo = ref<UserStatisticsCountRespVO>()
|
||||||
const fetchUserStatistics = async () => {
|
const fetchUserStatistics = async () => {
|
||||||
@ -102,19 +111,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleLogin = () => {
|
const handleLogin = () => {
|
||||||
app.$openLogin()
|
app.$openLogin()
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleRegister = () => {
|
const handleRegister = () => {
|
||||||
app.$openRegister()
|
app.$openRegister()
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleLoginPhone = () => {
|
const handleLoginPhone = () => {
|
||||||
app.$openLogin('verify')
|
app.$openLogin('verify')
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleLoginEmail = () => {
|
const handleLoginEmail = () => {
|
||||||
app.$openLoginEmail()
|
app.$openLoginEmail()
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleUserInfo = () => {
|
const handleUserInfo = () => {
|
||||||
@ -124,15 +133,14 @@
|
|||||||
|
|
||||||
// 发布图纸
|
// 发布图纸
|
||||||
const handleDrawe = () => {
|
const handleDrawe = () => {
|
||||||
navigateTo('/upnew/drawe') // 修改为在新窗口打开
|
navigateTo('/upnew') // 修改为在新窗口打开
|
||||||
}
|
}
|
||||||
|
|
||||||
// 推出登录
|
// 推出登录
|
||||||
const handleLoginOut = () => {
|
const handleLoginOut = () => {
|
||||||
REFRESHTOKEN.removeToken()
|
clearNuxtState(['token', 'userInfo'])
|
||||||
userStore.setToken('')
|
userStore.logout()
|
||||||
userStore.setUserId('')
|
userStore.$reset()
|
||||||
userStore.setRefreshToken('')
|
|
||||||
window.location.reload()
|
window.location.reload()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +149,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
if (isLogin.value) {
|
if (isLogin.value && import.meta.client) {
|
||||||
fetchUserStatistics()
|
fetchUserStatistics()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -2,27 +2,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="main-content">
|
<div class="main-content">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div class="h-424px w-957px">
|
<div class="h-[424px] w-[957px]">
|
||||||
<el-carousel height="424px" indicator-position="none">
|
<el-carousel height="424px" indicator-position="none">
|
||||||
<el-carousel-item v-for="(item, index) in bannerList" :key="index">
|
<el-carousel-item v-for="(item, index) in bannerList" :key="index">
|
||||||
<el-image
|
<el-image :src="item.content" class="w-[100%]" :class="{ 'cursor-pointer': item.url }" fit="cover" @click="handleClick(item.url)" />
|
||||||
:src="item.content"
|
|
||||||
class="w-100%"
|
|
||||||
:class="{ 'cursor-pointer': item.url }"
|
|
||||||
fit="cover"
|
|
||||||
@click="handleClick(item.url)"
|
|
||||||
/>
|
|
||||||
</el-carousel-item>
|
</el-carousel-item>
|
||||||
</el-carousel>
|
</el-carousel>
|
||||||
</div>
|
</div>
|
||||||
<LoginForm />
|
<LoginForm />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="box-border h-[56px] w-[1219px] flex items-center border border-[#EEEEEE] border-solid border-t-none bg-[#FFFFFF] pl-[10px] line-height-[46px]">
|
||||||
class="box-border h-56px w-1219px flex items-center border border-[#EEEEEE] border-solid border-t-none bg-[#FFFFFF] pl-10px line-height-46px"
|
<img src="~/assets/images/voice.png" alt="" srcset="" class="mr-[10px] h-[15px] w-[16px]" />
|
||||||
>
|
|
||||||
<img src="~/assets/images/voice.png" alt="" srcset="" class="mr-10px h-15px w-16px" />
|
|
||||||
<Vue3Marquee :duration="10" direction="normal" pause-on-hover>
|
<Vue3Marquee :duration="10" direction="normal" pause-on-hover>
|
||||||
· 经典来袭,SolidWorks装配经典案例之气动发动机
|
<template v-for="(item, index) in noticeList" :key="index"> {{ item }} </template>
|
||||||
</Vue3Marquee>
|
</Vue3Marquee>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -33,7 +25,7 @@
|
|||||||
import LoginForm from './LoginForm.vue'
|
import LoginForm from './LoginForm.vue'
|
||||||
import { Vue3Marquee } from 'vue3-marquee'
|
import { Vue3Marquee } from 'vue3-marquee'
|
||||||
|
|
||||||
import { getSettingPage } from '~/api/home/index'
|
import { getSettingPage, getNoticeList } from '~/api/home/index'
|
||||||
|
|
||||||
const pageReq = reactive({
|
const pageReq = reactive({
|
||||||
type: 1,
|
type: 1,
|
||||||
@ -50,6 +42,8 @@
|
|||||||
navigateTo(url)
|
navigateTo(url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { data: noticeList } = await getNoticeList()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@ -155,7 +155,7 @@
|
|||||||
const all = [{ id: '0', name: '全部分类', children: [] }]
|
const all = [{ id: '0', name: '全部分类', children: [] }]
|
||||||
if (Array.isArray(res.data) && res.data?.length > 0) {
|
if (Array.isArray(res.data) && res.data?.length > 0) {
|
||||||
const total = [...res.data, ...all]
|
const total = [...res.data, ...all]
|
||||||
// query.projectTypeDay = total[0]?.id || ''
|
query.projectTypeDay = total[0]?.id || ''
|
||||||
// query.projectType = total[0]!.children?.[0]?.id || ''
|
// query.projectType = total[0]!.children?.[0]?.id || ''
|
||||||
return total
|
return total
|
||||||
}
|
}
|
||||||
@ -206,10 +206,10 @@
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
const handleHover = (item: ProjectDictNodeVO) => {
|
const handleHover = (item: ProjectDictNodeVO) => {
|
||||||
query.projectTypeDay = item.id || ''
|
|
||||||
if (item.name === '全部分类') return
|
if (item.name === '全部分类') return
|
||||||
|
query.projectTypeDay = item.id || ''
|
||||||
// projectTypeListChildren.value = item.children || []
|
// projectTypeListChildren.value = item.children || []
|
||||||
query.projectType = item.children?.[0].id || ''
|
// query.projectType = item.id || ''
|
||||||
// 热门数据
|
// 热门数据
|
||||||
getHotTop()
|
getHotTop()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,8 +44,6 @@
|
|||||||
const sideMenu = ref()
|
const sideMenu = ref()
|
||||||
const menuItemRefs = ref<HTMLElement[]>([])
|
const menuItemRefs = ref<HTMLElement[]>([])
|
||||||
|
|
||||||
// const menuItems = ref<ProjectDictNodeVO[]>([]);
|
|
||||||
|
|
||||||
// 等待数据加载完成再进行渲染 :courseData 对data进行别名赋值
|
// 等待数据加载完成再进行渲染 :courseData 对data进行别名赋值
|
||||||
const {
|
const {
|
||||||
data: menuItems,
|
data: menuItems,
|
||||||
@ -64,9 +62,6 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
const showSubMenu = (index: number) => {
|
const showSubMenu = (index: number) => {
|
||||||
// if (menuItems.value.length === index + 1) {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
activeIndex.value = index
|
activeIndex.value = index
|
||||||
const dom = menuItemRefs.value[index].getBoundingClientRect()
|
const dom = menuItemRefs.value[index].getBoundingClientRect()
|
||||||
console.log(dom)
|
console.log(dom)
|
||||||
@ -78,21 +73,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleSubmenuClick = (primary: ProjectDictNodeVO) => {
|
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`)
|
navigateTo(`/drawe/${primary.id}/1/12/-1`)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +149,7 @@
|
|||||||
.menu-item {
|
.menu-item {
|
||||||
/* position: relative; */
|
/* position: relative; */
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 11px 24px;
|
padding: 9px 24px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
/* transition: all 0.3s ease; */
|
/* transition: all 0.3s ease; */
|
||||||
color: #333;
|
color: #333;
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="ma-auto w-1440px">
|
<div class="ma-auto w-1440px">
|
||||||
|
<SeoHead :title="tdkData?.title" :description="tdkData?.describeText" :keywords="tdkData?.keyword" />
|
||||||
<!-- 搜索 -->
|
<!-- 搜索 -->
|
||||||
<KlSearch></KlSearch>
|
<KlSearch></KlSearch>
|
||||||
<!-- 菜单 -->
|
<!-- 菜单 -->
|
||||||
@ -29,6 +30,12 @@
|
|||||||
import PopularDrawings from '~/pages/home/components/PopularDrawings.vue'
|
import PopularDrawings from '~/pages/home/components/PopularDrawings.vue'
|
||||||
import Leaderboard from '~/pages/home/components/Leaderboard.vue'
|
import Leaderboard from '~/pages/home/components/Leaderboard.vue'
|
||||||
import LearningRecommendations from '~/pages/home/components/LearningRecommendations.vue'
|
import LearningRecommendations from '~/pages/home/components/LearningRecommendations.vue'
|
||||||
|
import { getTDK } from '~/api/home/index'
|
||||||
|
|
||||||
|
const { data: tdkData } = useAsyncData('get-tdk-home', async () => {
|
||||||
|
const res = await getTDK()
|
||||||
|
return res.data
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
14
pages/mobile/channel/index.vue
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<template>
|
||||||
|
<div class="page-channel">
|
||||||
|
<div class="text">交流频道</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
definePageMeta({ layout: 'm' })
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.page-channel { padding: 16px; }
|
||||||
|
.text { font-size: 16px; }
|
||||||
|
</style>
|
||||||
14
pages/mobile/find/index.vue
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<template>
|
||||||
|
<div class="page-find">
|
||||||
|
<div class="text">发现</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
definePageMeta({ layout: 'm' })
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.page-find { padding: 16px; }
|
||||||
|
.text { font-size: 16px; }
|
||||||
|
</style>
|
||||||