Compare commits
81 Commits
2fe36051f8
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ecff344de | |||
| 7a8f096513 | |||
| 80a48e1e71 | |||
| f6a1dc3513 | |||
| cb89a861c1 | |||
| 18d93d3a2a | |||
| 31f8d6d23d | |||
| 316d82b3ad | |||
| 8e26ae9cde | |||
| 22539f3839 | |||
| 469900d3ac | |||
| 9675261481 | |||
| 3153a35daf | |||
| 966c5feb5e | |||
| f7784e8305 | |||
| 048dd1fe65 | |||
| dbc15f5f52 | |||
| e30abf7f83 | |||
| 7a91eddbb4 | |||
| e036c88535 | |||
| 4fb57c13c7 | |||
| 29c34caa94 | |||
| 8593a8b52e | |||
| ede6eec78b | |||
| f0e65ee2ab | |||
| b6fbdb2b26 | |||
| 8c265e3a21 | |||
| 2c8eda876d | |||
| 229916000f | |||
| 7fe259299e | |||
| a2c2a87e38 | |||
| 0de028d6eb | |||
| 41922df68b | |||
| 639486cd29 | |||
| f4e80bc25a | |||
| e02c17066d | |||
| 53121ca5f7 | |||
| 17a70cf2ac | |||
| 6b8e6918aa | |||
| 6074bf9c8d | |||
| 9b46dacbb1 | |||
| cb81e9f0df | |||
| fadab4eacb | |||
| 3f1431f972 | |||
| 9edc63ff4f | |||
| 067dbae5ce | |||
| bc006c404b | |||
| 170113e11c | |||
| 0f96406b5a | |||
| dc628e3494 | |||
| 600c3e9f18 | |||
| 720ff7484c | |||
| 7413b1a74d | |||
| 9acc229704 | |||
| 64d0696cb9 | |||
| 2b2586293d | |||
| 0c59337af3 | |||
| dd46a68b6c | |||
| 84a7263f36 | |||
| bfa0f5e6bd | |||
| 4263a0a235 | |||
| e021ac1e05 | |||
| 5a2be1bc3b | |||
| bc26b478a9 | |||
| 7291768b03 | |||
| 63fa551041 | |||
| cdcb6e76c2 | |||
| 7413a1f8ea | |||
| 6e2d5989eb | |||
| 0fe0f14193 | |||
| 43724c4d4d | |||
| 587dbbeca6 | |||
| 9bc983793f | |||
| 366b48188d | |||
| a2fe21a497 | |||
| b603d9d854 | |||
| ee8ce32af6 | |||
| 38f6d8c062 | |||
| bf86652ff2 | |||
| b7113c4e12 | |||
| 0de28e554a |
17
.prettierrc.cjs
Normal file
17
.prettierrc.cjs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
module.exports = {
|
||||||
|
singleQuote: true, // 使用单引号
|
||||||
|
printWidth: 160,
|
||||||
|
tabWidth: 2,
|
||||||
|
useTabs: false,
|
||||||
|
semi: false,
|
||||||
|
vueIndentScriptAndStyle: true,
|
||||||
|
quoteProps: 'as-needed',
|
||||||
|
bracketSpacing: true,
|
||||||
|
arrowParens: 'always',
|
||||||
|
insertPragma: false,
|
||||||
|
requirePragma: false,
|
||||||
|
trailingComma: 'es5',
|
||||||
|
proseWrap: 'never',
|
||||||
|
htmlWhitespaceSensitivity: 'strict',
|
||||||
|
endOfLine: 'auto',
|
||||||
|
}
|
||||||
10
.vscode/settings.json
vendored
10
.vscode/settings.json
vendored
@ -1,5 +1,5 @@
|
|||||||
{
|
// {
|
||||||
"editor.formatOnSave": true,
|
// "editor.formatOnSave": true,
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
// "editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
"prettier.configPath": "./.prettierrc"
|
// "prettier.configPath": "../.prettierrc",
|
||||||
}
|
// }
|
||||||
@ -20,7 +20,7 @@ import type {
|
|||||||
* @return {Promise}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
export const page = (params: TpageReq) => {
|
export const page = (params: TpageReq) => {
|
||||||
return useFetchRequest.get<IResponse<TpageRes>>('/prod-api/app-api/business/posts/page', params)
|
return useDollarFetchRequest.get<IResponse<TpageRes>>('/prod-api/app-api/business/posts/page', { query: params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,7 +35,7 @@ export const create = (params: TcreateReq) => {
|
|||||||
* @return {Promise}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
export const list = () => {
|
export const list = () => {
|
||||||
return useFetchRequest.get<IResponse<TlistRes[]>>('/prod-api/app-api/business/channel/list')
|
return useDollarFetchRequest.get<IResponse<TlistRes[]>>('/prod-api/app-api/business/channel/list')
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 获得论坛频道列表
|
* 获得论坛频道列表
|
||||||
@ -56,7 +56,7 @@ export const postsDelete = (params: { id: number }) => {
|
|||||||
* @return {Promise}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
export const getChannelDetail = (params: { id: string }) => {
|
export const getChannelDetail = (params: { id: string }) => {
|
||||||
return useFetchRequest.get<IResponse<TGetChannelPostsRes>>('/prod-api/app-api/business/posts/get', params)
|
return useFetchRequest.get<IResponse<TGetChannelPostsRes>>('/prod-api/app-api/business/posts/get', { query: params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -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', params)
|
return useFetchRequest.get<IResponse<PageResultPostsCommentRespVO>>('/prod-api/app-api/business/posts-comment/page', { query: params })
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 创建帖子评论
|
* 创建帖子评论
|
||||||
@ -93,42 +93,47 @@ export const sendKefuMessage = (params: SingleMessageVo) => {
|
|||||||
* 获得消息记录分页
|
* 获得消息记录分页
|
||||||
*/
|
*/
|
||||||
export const getMessagePage = (params: { pageNo: number; pageSize: number; fromId?: number; msgType?: number; topic: string }) => {
|
export const getMessagePage = (params: { pageNo: number; pageSize: number; fromId?: number; msgType?: number; topic: string }) => {
|
||||||
return useFetchRequest.get<IResponse<PageResultMessageRespVO>>('/prod-api/app-api/mqtt/message/page', params)
|
return useDollarFetchRequest.get<IResponse<PageResultMessageRespVO>>('/prod-api/app-api/mqtt/message/page', { query: params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 会话列表
|
* 会话列表
|
||||||
*/
|
*/
|
||||||
export const conversationList = () => {
|
export const conversationList = () => {
|
||||||
return useFetchRequest.get<IResponse<PageResultSessionRespVO[]>>('/prod-api/app-api/mqtt/session/list')
|
return useDollarFetchRequest.get<IResponse<PageResultSessionRespVO[]>>('/prod-api/app-api/mqtt/session/list')
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取聊天记录
|
* 获取聊天记录
|
||||||
*/
|
*/
|
||||||
export const getChatDetail = (params: { sessionId: number; pageNo: number; pageSize: number }) => {
|
export const getChatDetail = (params: { sessionId: number; pageNo: number; pageSize: number }) => {
|
||||||
return useFetchRequest.get<IResponse<PageResultMessageRespVO>>('/prod-api/app-api/mqtt/message/pageBySession', params)
|
return useDollarFetchRequest.get<IResponse<PageResultMessageRespVO>>('/prod-api/app-api/mqtt/message/pageBySession', { query: params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清空未读信息
|
* 清空未读信息
|
||||||
*/
|
*/
|
||||||
export const clearUnreadMessage = (params: { id: number }) => {
|
export const clearUnreadMessage = (params: { id: number }) => {
|
||||||
return useDollarFetchRequest.put<IResponse<boolean>>('/prod-api/app-api/mqtt/session/clear', { params })
|
return useDollarFetchRequest.put<IResponse<boolean>>('/prod-api/app-api/mqtt/session/clear?id=' + params.id, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得论坛频道
|
* 获得论坛频道
|
||||||
*/
|
*/
|
||||||
export const getChannelLunTanDetail = (params: { id: string }) => {
|
export const getChannelLunTanDetail = (params: { id: string }) => {
|
||||||
return useFetchRequest.get<IResponse<ChannelRespVO>>('/prod-api/app-api/business/channel/get', params)
|
return useDollarFetchRequest.get<IResponse<ChannelRespVO>>('/prod-api/app-api/business/channel/get', { query: params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建论坛关注
|
* 创建论坛关注
|
||||||
*/
|
*/
|
||||||
export const createChannelFollow = (params: { channelId: string }) => {
|
export const createChannelFollow = (params: { channelId: string }) => {
|
||||||
return useDollarFetchRequest.post<IResponse<boolean>>('/prod-api/app-api/business/channel-follow/create', params)
|
return useDollarFetchRequest.post<IResponse<boolean>>(`/prod-api/app-api/business/channel-follow/create?channelId=${params.channelId}`, {}, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
'Accept': 'application/json'
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -36,7 +36,7 @@ export const creatFile = (params: fileCreateReqVO) => {
|
|||||||
* @return {Promise}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
export const getUserInfo = () => {
|
export const getUserInfo = () => {
|
||||||
return useFetchRequest.get<IResponse<AppMemberUserInfoRespVO>>('/prod-api/app-api/member/user/get')
|
return useDollarFetchRequest.get<IResponse<AppMemberUserInfoRespVO>>('/prod-api/app-api/member/user/get')
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,5 +59,5 @@ export const sendSms = (params: { mobile: string; scene: number }) => {
|
|||||||
* 获得站内信
|
* 获得站内信
|
||||||
*/
|
*/
|
||||||
export const getMessage = (params: { id: number }) => {
|
export const getMessage = (params: { id: number }) => {
|
||||||
return useFetchRequest.get<IResponse<NotifyMessageRespVO>>('/prod-api/app-api/system/notify-message/get', { params })
|
return useDollarFetchRequest.get<IResponse<NotifyMessageRespVO>>('/prod-api/app-api/system/notify-message/get', { query:params })
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ 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', { params })
|
return useFetchRequest.get<IResponse<ProjectRespVO>>('/prod-api/app-api/business/app/project-draw/preview', { query:params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,7 +15,7 @@ export const getDetail = (params: { id?: number | string }) => {
|
|||||||
* @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 }) => {
|
||||||
return useFetchRequest.get<IResponse<PageResultProjectCommentResVO>>('/prod-api/app-api/business/app/project-comment/page', { params })
|
return useDollarFetchRequest.get<IResponse<PageResultProjectCommentResVO>>('/prod-api/app-api/business/app/project-comment/page', { query:params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,7 +31,7 @@ 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', { params })
|
return useFetchRequest.get<IResponse<ProjectDrawPageRespVO[]>>('/prod-api/app-api/business/app/project-draw/top-list', { query:params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import type {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const hotTop = (params: ThotTopReq) => {
|
export const hotTop = (params: ThotTopReq) => {
|
||||||
return useDollarFetchRequest.get<IResponse<ProjectDrawPageRespVO[]>>('/prod-api/app-api/business/app/project-draw/hot-top', { params })
|
return useDollarFetchRequest.get<IResponse<ProjectDrawPageRespVO[]>>('/prod-api/app-api/business/app/project-draw/hot-top', { query: params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,21 +24,21 @@ export const hotTop = (params: ThotTopReq) => {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const recommendTop = (params: ThotTopReq) => {
|
export const recommendTop = (params: ThotTopReq) => {
|
||||||
return useFetchRequest.get<IResponse<ProjectDrawPageRespVO[]>>('/prod-api/app-api/business/app/project-draw/recommend-top', { params })
|
return useFetchRequest.get<IResponse<ProjectDrawPageRespVO[]>>('/prod-api/app-api/business/app/project-draw/recommend-top', { query: params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取最新图纸信息
|
* 获取最新图纸信息
|
||||||
*/
|
*/
|
||||||
export const newDraw = (params: { type: number; limit: number }) => {
|
export const newDraw = (params: { type: number; limit: number }) => {
|
||||||
return useDollarFetchRequest.get<IResponse<ProjectDrawPageRespVO[]>>('/prod-api/app-api/business/project/index/draw-new', { params })
|
return useFetchRequest.get<IResponse<ProjectDrawPageRespVO[]>>('/prod-api/app-api/business/project/index/draw-new', { query: params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 首页-热点标签
|
* 首页-热点标签
|
||||||
*/
|
*/
|
||||||
export const hotTag = (params: { type: number; limit: number; size: number }) => {
|
export const hotTag = (params: { type: number; limit: number; size: number }) => {
|
||||||
return useDollarFetchRequest.get<IResponse<ProjectDictNodeVO[]>>('/prod-api/app-api/business/project/index/index-hot-tab', { params })
|
return useFetchRequest.get<IResponse<ProjectDictNodeVO[]>>('/prod-api/app-api/business/project/index/index-hot-tab', { query: params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,7 +59,7 @@ export const top = (params: { type: number; limit: number }) => {
|
|||||||
* 获取用户top数据
|
* 获取用户top数据
|
||||||
*/
|
*/
|
||||||
export const userTop = (params: { type?: number }) => {
|
export const userTop = (params: { type?: number }) => {
|
||||||
return useDollarFetchRequest.get<IResponse<ProjectTrendingScoreUserInfoVO[]>>('/prod-api/app-api/business/project/index/user-top', { params })
|
return useFetchRequest.get<IResponse<ProjectTrendingScoreUserInfoVO[]>>('/prod-api/app-api/business/project/index/user-top', { query: params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,13 +72,19 @@ export const settinngPage = (params: { pageNo?: number; pageSize: number; type:
|
|||||||
* 获得首页设置信息分页
|
* 获得首页设置信息分页
|
||||||
*/
|
*/
|
||||||
export const getSettingPage = (params: { type: number }) => {
|
export const getSettingPage = (params: { type: number }) => {
|
||||||
return useFetchRequest.get<IResponse<PageResultIndexSettingRespVO[]>>('/prod-api/app-api/system/index-setting/list', { params })
|
return useFetchRequest.get<IResponse<PageResultIndexSettingRespVO[]>>('/prod-api/app-api/system/index-setting/list', { query: params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 首页-标签2
|
* 首页-标签2
|
||||||
*/
|
*/
|
||||||
export const tab2 = () => {
|
export const tab2 = () => {
|
||||||
return useFetchRequest.get<IResponse<ProjectDictNodeVO[]>>('/prod-api/app-api/business/project/index/index-tab2', {
|
return useFetchRequest.get<IResponse<ProjectDictNodeVO[]>>('/prod-api/app-api/business/project/index/index-tab2', {})
|
||||||
})
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取具有上下级关系的当前的名称
|
||||||
|
*/
|
||||||
|
export const getDictTree = (params: { type: number, id: number}) => {
|
||||||
|
return useDollarFetchRequest.get<IResponse<ProjectDictNodeVO[]>>('/prod-api/app-api/business/app/dict/path-by-id', { query: params })
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ export interface ThotTopReq {
|
|||||||
/** 类型: 1 图纸 2 文本 3 模型 */
|
/** 类型: 1 图纸 2 文本 3 模型 */
|
||||||
type: number
|
type: number
|
||||||
/** 项目分类 */
|
/** 项目分类 */
|
||||||
projectType: string
|
projectType: number
|
||||||
/** 是否国内 0 国外 1 国内 */
|
/** 是否国内 0 国外 1 国内 */
|
||||||
isDomestic: number
|
isDomestic: number
|
||||||
projectTypeTop?: string
|
projectTypeTop?: string
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import type { AppPayWalletPackageRespVO, PayOrderSubmitReqVO, PayOrderRespVO, Pa
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const listVip = () => {
|
export const listVip = () => {
|
||||||
return useFetchRequest.get<IResponse<AppPayWalletPackageRespVO[]>>('/prod-api/app-api/pay/wallet-recharge-package/list-vip', {})
|
return useDollarFetchRequest.get<IResponse<AppPayWalletPackageRespVO[]>>('/prod-api/app-api/pay/wallet-recharge-package/list-vip', {})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,14 +36,14 @@ export const createOrder = (params: { spuId: number }) => {
|
|||||||
* 获得钱包充值套餐列表
|
* 获得钱包充值套餐列表
|
||||||
*/
|
*/
|
||||||
export const listWalletRechargePackage = () => {
|
export const listWalletRechargePackage = () => {
|
||||||
return useFetchRequest.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', params)
|
return useDollarFetchRequest.get<IResponse<PayOrderRespVO>>('/prod-api/app-api/pay/order/get', {query:params})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -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 useFetchRequest.get<IResponse<PageResultAppPayWalletRechargeRespVO>>('/prod-api/app-api/pay/wallet-transaction/page', params)
|
return useDollarFetchRequest.get<IResponse<PageResultAppPayWalletRechargeRespVO>>('/prod-api/app-api/pay/wallet-transaction/page', {query:params})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ import type {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const getUserInfo = () => {
|
export const getUserInfo = () => {
|
||||||
return useFetchRequest.get<IResponse<UserExtendRespVO>>('/prod-api/app-api/member/user-extend/get', {})
|
return useDollarFetchRequest.get<IResponse<UserExtendRespVO>>('/prod-api/app-api/member/user-extend/get', {})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,13 +66,13 @@ export const updateUserAuthInfo = (params: UserAuthInfoRespVO) => {
|
|||||||
* 获得内容信息分页
|
* 获得内容信息分页
|
||||||
*/
|
*/
|
||||||
export const getContentPage = (params: { type: number }) => {
|
export const getContentPage = (params: { type: number }) => {
|
||||||
return useFetchRequest.get<IResponse<PageResultProjectHistoryResVO>>('/prod-api/app-api/business/project-history/page', 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 useFetchRequest.get<IResponse<PageResultProjectHistoryResVO>>('/prod-api/app-api/business/project-member-file/page', params)
|
return useDollarFetchRequest.get<IResponse<PageResultProjectHistoryResVO>>('/prod-api/app-api/business/project-member-file/page', {query:params})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,54 +92,54 @@ export const signIn = () => {
|
|||||||
* 获得用户积分记录分页
|
* 获得用户积分记录分页
|
||||||
*/
|
*/
|
||||||
export const getUserPointPage = (params: { pageNo: number; pageSize: number }) => {
|
export const getUserPointPage = (params: { pageNo: number; pageSize: number }) => {
|
||||||
return useFetchRequest.get<IResponse<PageResultMemberPointRecordRespVO>>('/prod-api/app-api/member/point/record/page', 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 useFetchRequest.get<IResponse<UserStatisticsLineRespVO>>('/prod-api/app-api/member/statistics/line', 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 useFetchRequest.get<IResponse<UserStatisticsBarRespVO>>('/prod-api/app-api/member/statistics/bar', params)
|
return useDollarFetchRequest.get<IResponse<UserStatisticsBarRespVO>>('/prod-api/app-api/member/statistics/bar', {query:params})
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 我的数据统计 包括我的金币 我的关注 我的发布等等
|
* 我的数据统计 包括我的金币 我的关注 我的发布等等
|
||||||
*/
|
*/
|
||||||
export const getUserStatistics = () => {
|
export const getUserStatistics = () => {
|
||||||
return useFetchRequest.get<IResponse<UserStatisticsCountRespVO>>('/prod-api/app-api/member/statistics/count', {})
|
return useDollarFetchRequest.get<IResponse<UserStatisticsCountRespVO>>('/prod-api/app-api/member/statistics/count', {})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得项目订单用户收藏信息分页
|
* 获得项目订单用户收藏信息分页
|
||||||
*/
|
*/
|
||||||
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 useFetchRequest.get<IResponse<PageResultProjectMemberFavoritesRespVO>>('/prod-api/app-api/business/project-member-favorites/page', 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 useFetchRequest.get<IResponse<PageResultProjectHistoryResVO>>('/prod-api/app-api/business/app/project-draw/my-page', 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -15,5 +15,5 @@ export const create = (params: TcreateReq) => {
|
|||||||
* 获得内容信息分页
|
* 获得内容信息分页
|
||||||
*/
|
*/
|
||||||
export const page = (params: TpageReq) => {
|
export const page = (params: TpageReq) => {
|
||||||
return useFetchRequest.get<IResponse<TpageRes>>('/prod-api/app-api/business/app/project-resource/page', params)
|
return useFetchRequest.get<IResponse<TpageRes>>('/prod-api/app-api/business/app/project-resource/page', {query:params})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,8 +15,16 @@ export const create = (params: TcreateReq) => {
|
|||||||
* @param params
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const parent = (params: { type: string | number; parentId: number }) => {
|
export const parent = (params: { type: string | number; parentId: number | string }) => {
|
||||||
return useFetchRequest.get<IResponse<parentRes[]>>('/prod-api/app-api/business/app/dict/parent', params)
|
return useFetchRequest.get<IResponse<parentRes[]>>('/prod-api/app-api/business/app/dict/parent', { query: params })
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取具有上下级的字典信息
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const parentV2 = (params: { type: string | number; parentId: number | string }) => {
|
||||||
|
return useDollarFetchRequest.get<IResponse<parentRes[]>>('/prod-api/app-api/business/app/dict/parent', { query: params })
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 获取具有上下级的字典信息
|
* 获取具有上下级的字典信息
|
||||||
@ -32,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', params)
|
return useFetchRequest.get<IResponse<boolean>>('/prod-api/app-api/business/app/dict/label-keywords', {query:params})
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 获取格式类型字典信息
|
* 获取格式类型字典信息
|
||||||
@ -48,7 +56,7 @@ export const labels = (params: { type: string | number }) => {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const page = (params: pageReq) => {
|
export const page = (params: pageReq) => {
|
||||||
return useFetchRequest.get<IResponse<pageRes>>('/prod-api/app-api/business/app/project-draw/page', params)
|
return useFetchRequest.get<IResponse<pageRes>>('/prod-api/app-api/business/app/project-draw/page', { query: params })
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 获得项目表内容信息分页
|
* 获得项目表内容信息分页
|
||||||
|
|||||||
@ -52,7 +52,7 @@ export interface pageReq {
|
|||||||
projectId?: number | string
|
projectId?: number | string
|
||||||
title?: string
|
title?: string
|
||||||
ownedUserId?: string
|
ownedUserId?: string
|
||||||
editions?: string
|
editions?: any
|
||||||
labels?: any[]
|
labels?: any[]
|
||||||
type?: number // 类型: 1 图纸 2 文本 3 模型
|
type?: number // 类型: 1 图纸 2 文本 3 模型
|
||||||
source?: number | string
|
source?: number | string
|
||||||
@ -60,7 +60,7 @@ export interface pageReq {
|
|||||||
status?: any
|
status?: any
|
||||||
createAddress?: string
|
createAddress?: string
|
||||||
createIp?: string
|
createIp?: string
|
||||||
projectType?: string
|
projectType?: any
|
||||||
}
|
}
|
||||||
export interface pageRes {
|
export interface pageRes {
|
||||||
list: {
|
list: {
|
||||||
|
|||||||
29
app.vue
29
app.vue
@ -1,6 +1,33 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="flex flex-col flex-1">
|
||||||
<NuxtLoadingIndicator />
|
<NuxtLoadingIndicator />
|
||||||
|
<NuxtLayout>
|
||||||
<NuxtPage />
|
<NuxtPage />
|
||||||
|
</NuxtLayout>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
|||||||
@ -5,12 +5,20 @@ ul,
|
|||||||
li {
|
li {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-family: Microsoft YaHei, PingFang SC, Helvetica Neue, Helvetica, Hiragino Sans GB, Arial, sans-serif;
|
font-family:
|
||||||
|
Microsoft YaHei,
|
||||||
|
PingFang SC,
|
||||||
|
Helvetica Neue,
|
||||||
|
Helvetica,
|
||||||
|
Hiragino Sans GB,
|
||||||
|
Arial,
|
||||||
|
sans-serif;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
min-width: 1500px;
|
min-width: 1500px;
|
||||||
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
img {
|
img {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
@ -26,7 +34,7 @@ a {
|
|||||||
--el-color-primary-light-1: rgba(8, 88, 247, 0.9);
|
--el-color-primary-light-1: rgba(8, 88, 247, 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
#app {
|
#__nuxt {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mt-30px">
|
<div class="mt-[30px] w-[100%]">
|
||||||
<div class="h-48px w-938px 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" />
|
||||||
<div class="flex-1 pl-8px">
|
<div class="flex-1 pl-[8px]">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<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>
|
||||||
@ -19,12 +19,12 @@
|
|||||||
:page-size="query.pageSize"
|
:page-size="query.pageSize"
|
||||||
layout="prev, pager, next"
|
layout="prev, pager, next"
|
||||||
:total="result.total"
|
:total="result.total"
|
||||||
class="mt-10px"
|
class="mt-[10px]"
|
||||||
@current-change="handleCurrentChange"
|
@current-change="handleCurrentChange"
|
||||||
/>
|
/>
|
||||||
<el-input v-model="commentContent" type="textarea" :rows="6" placeholder="请输入内容" class="mt-20px w-100%"></el-input>
|
<el-input v-model="commentContent" type="textarea" :rows="6" placeholder="请输入内容" class="mt-[20px] w-[100%]"></el-input>
|
||||||
<div>
|
<div>
|
||||||
<el-button type="primary" class="mt-10px h-40px w-101px rounded-4px text-16px text-[#FFFFFF] font-bold" @click="handleCreateComment">
|
<el-button type="primary" class="mt-[10px] h-[40px] w-[101px] rounded-[4px] text-[16px] text-[#FFFFFF] font-bold" @click="handleCreateComment">
|
||||||
发表评论
|
发表评论
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@ -87,6 +87,8 @@
|
|||||||
() => props.relationId,
|
() => props.relationId,
|
||||||
() => {
|
() => {
|
||||||
handleGetCommentList()
|
handleGetCommentList()
|
||||||
|
},{
|
||||||
|
immediate: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
<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-[10px] text-[16px] text-[#999999] font-normal"
|
||||||
>共<span class="color-#1A65FF">{{ result.total }}</span
|
>共<span class="color-[#1A65FF]">{{ result?.total }}</span
|
||||||
>个筛选结果</div
|
>个筛选结果</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">
|
||||||
<CardPicture :item-info="item" />
|
<CardPicture :item-info="item" />
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-empty v-if="!result.list.length" :image="emptyImg"></el-empty>
|
<el-empty v-if="!result?.list.length" :image="emptyImg"></el-empty>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -27,14 +27,14 @@
|
|||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const result = defineModel<pageRes>('result', {
|
const result = defineModel<pageRes | null>('result', {
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const tabBar = ref([
|
const tabBar = ref([
|
||||||
{
|
{
|
||||||
label: '图纸推荐',
|
label: '图纸推荐',
|
||||||
value: '',
|
value: -1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '原创图纸',
|
label: '原创图纸',
|
||||||
@ -1,18 +1,18 @@
|
|||||||
<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="tabIndex" :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-[10px] text-[16px] text-[#999999] font-normal"
|
||||||
>共<span class="color-#1A65FF">{{ result.total }}</span
|
>共<span class="color-[#1A65FF]">{{ result?.total }}</span
|
||||||
>个筛选结果</div
|
>个筛选结果</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">
|
||||||
<CardPicture :item-info="item" />
|
<CardPicture :item-info="item" />
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-empty v-if="!result.list.length" description="暂无数据"></el-empty>
|
<el-empty v-if="!result?.list.length" description="暂无数据"></el-empty>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -20,6 +20,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import KlTabBar from '~/components/kl-tab-bar/index.vue'
|
import KlTabBar from '~/components/kl-tab-bar/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'
|
||||||
|
|
||||||
@ -31,26 +32,26 @@
|
|||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
const result = defineModel<pageRes>('modelValue', {
|
const result = defineModel<pageRes| null>('modelValue', {
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
const query = defineModel<any>('query', {
|
const query = defineModel<any>('query', {
|
||||||
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>
|
||||||
@ -1,33 +1,33 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mb-20px w-100% cursor-pointer overflow-hidden border border-[#EEEEEE] rounded-10px border-solid bg-[#FFFFFF]" @click="handleClick">
|
<div class="mb-[20px] w-[100%] cursor-pointer overflow-hidden border border-[#EEEEEE] rounded-[10px] border-solid bg-[#FFFFFF]" @click="handleClick">
|
||||||
<div>
|
<div>
|
||||||
<el-image :src="props.itemInfo.iconUrl" class="h-216px w-100%" fit="cover"></el-image>
|
<el-image :src="props.itemInfo.iconUrl" class="h-[216px] w-[100%]" fit="cover"></el-image>
|
||||||
</div>
|
</div>
|
||||||
<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">{{ props.itemInfo.title }}</div>
|
||||||
<div class="mt-8px text-15px text-[#999999] font-normal">by {{ props.itemInfo?.ownedUserIdInfo?.nickName }}</div>
|
<div class="mt-[8px] text-[15px] text-[#999999] font-normal">by {{ props.itemInfo?.ownedUserIdInfo?.nickName }}</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-[24px] 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]" />
|
||||||
<span class="color-#666">{{ props.itemInfo.previewPoint }}</span>
|
<span class="color-[#666]">{{ props.itemInfo.previewPoint }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mr-9px flex items-center">
|
<div class="mr-[9px] flex items-center">
|
||||||
<img src="~/assets/images/add.png" alt="" srcset="" class="mr-2px h-22px" />
|
<img src="~/assets/images/add.png" alt="" srcset="" class="mr-[2px] h-[22px]" />
|
||||||
<span class="color-#666">{{ props.itemInfo.hotPoint }}</span>
|
<span class="color-[#666]">{{ props.itemInfo.hotPoint }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="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-[17px]" />
|
||||||
<span class="color-#666">{{ props.itemInfo.commentsPoint }}</span>
|
<span class="color-[#666]">{{ props.itemInfo.commentsPoint }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="h-30px w-90px cursor-pointer border border-[#1A65FF] rounded-15px border-solid text-center line-height-30px"
|
<div class="h-[30px] w-[90px] cursor-pointer border border-[#1A65FF] rounded-[15px] border-solid text-center line-height-[30px]"
|
||||||
><span class="text-14px text-[#1A65FF] font-normal">查看详情</span></div
|
><span class="text-[14px] text-[#1A65FF] font-normal">查看详情</span></div
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -46,11 +46,11 @@
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = async () => {
|
||||||
console.log(props.itemInfo)
|
console.log(props.itemInfo)
|
||||||
|
|
||||||
// 跳转到下载详情页 并且是单独开标签
|
// 跳转到下载详情页 并且是单独开标签
|
||||||
window.open(`/down-drawe-detail?id=${props.itemInfo.id}`, '_blank') // 修改为在新窗口打开
|
await navigateTo(`/down-drawe-detail/${props.itemInfo.id}`) // 修改为在新窗口打开
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<div v-if="visible" class="popup-overlay">
|
<div v-if="visible" class="popup-overlay">
|
||||||
<div class="popup-content">
|
<div class="popup-content">
|
||||||
<div class="login-container relative">
|
<div class="login-container relative">
|
||||||
<el-icon class="absolute right-0 top-0 cursor-pointer" @click="onClose()"><Close /></el-icon>
|
<el-icon class="absolute! right-0 top-0 cursor-pointer" @click="onClose()"><Close /></el-icon>
|
||||||
<!-- 左侧插图 -->
|
<!-- 左侧插图 -->
|
||||||
<div class="login-left">
|
<div class="login-left">
|
||||||
<img src="~/assets/images/login-illustration.png" alt="login" class="login-img" />
|
<img src="~/assets/images/login-illustration.png" alt="login" class="login-img" />
|
||||||
@ -87,7 +87,7 @@
|
|||||||
import { login, sendEmailCode, loginByEmail } from '~/api/login/index'
|
import { login, sendEmailCode, loginByEmail } from '~/api/login/index'
|
||||||
import refreshToken from '~/utils/RefreshToken'
|
import refreshToken from '~/utils/RefreshToken'
|
||||||
import { handleLoginQQ, handleLoginWechat, generateRandomString } from '~/utils/login'
|
import { handleLoginQQ, handleLoginWechat, generateRandomString } from '~/utils/login'
|
||||||
import useUserStore from '~/store/user'
|
import useUserStore from '~/stores/user'
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const { $openRegister, $openLogin } = useNuxtApp()
|
const { $openRegister, $openLogin } = useNuxtApp()
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<div v-if="visible" class="popup-overlay">
|
<div v-if="visible" class="popup-overlay">
|
||||||
<div class="popup-content">
|
<div class="popup-content">
|
||||||
<div class="login-container relative">
|
<div class="login-container relative">
|
||||||
<el-icon class="absolute right-0 top-0 cursor-pointer" @click="onClose()"><Close /></el-icon>
|
<el-icon class="absolute! right-[0px] top-[0px] cursor-pointer" @click="onClose()"><Close /></el-icon>
|
||||||
<!-- 左侧插图 -->
|
<!-- 左侧插图 -->
|
||||||
<div class="login-left">
|
<div class="login-left">
|
||||||
<img src="~/assets/images/login-illustration.png" alt="login" class="login-img" />
|
<img src="~/assets/images/login-illustration.png" alt="login" class="login-img" />
|
||||||
@ -23,7 +23,7 @@
|
|||||||
<el-form ref="formRef" :model="loginForm" :rules="rules" class="login-form">
|
<el-form ref="formRef" :model="loginForm" :rules="rules" class="login-form">
|
||||||
<template v-if="activeTab === 'account'">
|
<template v-if="activeTab === 'account'">
|
||||||
<el-form-item prop="mobile">
|
<el-form-item prop="mobile">
|
||||||
<el-input v-model="loginForm.mobile" placeholder="请输入用户名" :prefix-icon="User" class="w-322px!" />
|
<el-input v-model="loginForm.mobile" placeholder="请输入用户名" :prefix-icon="User" class="w-[322px]!" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="password">
|
<el-form-item prop="password">
|
||||||
<el-input v-model="loginForm.password" placeholder="请输入密码" :prefix-icon="Lock" type="password" />
|
<el-input v-model="loginForm.password" placeholder="请输入密码" :prefix-icon="Lock" type="password" />
|
||||||
@ -33,7 +33,7 @@
|
|||||||
<!-- 验证码登录 -->
|
<!-- 验证码登录 -->
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<el-form-item prop="phone">
|
<el-form-item prop="phone">
|
||||||
<el-input v-model="loginForm.phone" placeholder="请输入手机号" class="w-322px!" />
|
<el-input v-model="loginForm.phone" placeholder="请输入手机号" class="w-[322px]!" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="code">
|
<el-form-item prop="code">
|
||||||
<div class="verify-code-input">
|
<div class="verify-code-input">
|
||||||
@ -88,9 +88,12 @@
|
|||||||
import { sendSms } from '~/api/common/index'
|
import { sendSms } from '~/api/common/index'
|
||||||
import REFRESHTOKEN from '~/utils/RefreshToken'
|
import REFRESHTOKEN from '~/utils/RefreshToken'
|
||||||
import { handleLoginQQ, handleLoginWechat } from '~/utils/login'
|
import { handleLoginQQ, handleLoginWechat } from '~/utils/login'
|
||||||
import useUserStore from '~/store/user'
|
import useUserStore from '~/stores/user'
|
||||||
const { $openRegister, $openLogin, $openLoginEmail } = useNuxtApp()
|
const app = useNuxtApp()
|
||||||
|
const token = useToken();
|
||||||
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
const tokenCookie = useCookie<string | undefined>('token');
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
visible: {
|
visible: {
|
||||||
@ -157,7 +160,7 @@
|
|||||||
const handleRegister = () => {
|
const handleRegister = () => {
|
||||||
props.onClose()
|
props.onClose()
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
// $openRegister()
|
app.$openRegister()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 发送验证码
|
// 发送验证码
|
||||||
@ -208,8 +211,12 @@
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const res = await login(loginForm)
|
const res = await login(loginForm)
|
||||||
const { code, data, msg } = res
|
const { code, data} = res
|
||||||
if (code !== 0) return ElMessage.error(msg)
|
if (code === 0) {
|
||||||
|
// 设置cookie
|
||||||
|
tokenCookie.value = data.accessToken;
|
||||||
|
// 更新state
|
||||||
|
token.value = data.accessToken;
|
||||||
REFRESHTOKEN.setToken(data.accessToken, data.refreshToken)
|
REFRESHTOKEN.setToken(data.accessToken, data.refreshToken)
|
||||||
REFRESHTOKEN.setUserId(data.userId.toString())
|
REFRESHTOKEN.setUserId(data.userId.toString())
|
||||||
REFRESHTOKEN.setUserName(loginForm.mobile)
|
REFRESHTOKEN.setUserName(loginForm.mobile)
|
||||||
@ -222,6 +229,7 @@
|
|||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
userStore.getUserInfo()
|
userStore.getUserInfo()
|
||||||
// 登录成功
|
// 登录成功
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@ -262,7 +270,7 @@
|
|||||||
const handleLoginEmail = () => {
|
const handleLoginEmail = () => {
|
||||||
props.onClose()
|
props.onClose()
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
// $openLoginEmail()
|
app.$openLoginEmail()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -2,27 +2,27 @@
|
|||||||
<div class="box-border">
|
<div class="box-border">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="box-border h-100% h-55px w-221px flex items-center rd-2px bg-[#1A65FF] pl-24px text-white">
|
<div class="box-border h-[100%] h-[55px] w-[221px] flex items-center rd-[2px] bg-[#1A65FF] pl-[24px] text-white">
|
||||||
<img src="~/assets/images/1.png" alt="" srcset="" />
|
<img src="~/assets/images/1.png" alt="" srcset="" />
|
||||||
<span class="ml-12px text-16px">全部资源分类</span>
|
<span class="ml-[12px] text-[16px]">全部资源分类</span>
|
||||||
</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 menuItems"
|
||||||
:key="index"
|
:key="index"
|
||||||
:to="item.path"
|
:to="item.path"
|
||||||
class="parent-links relative rounded-lg px3 py2 text-[#1A65FF]"
|
class="parent-links relative rounded-lg px-3 py-2 text-[#1A65FF]"
|
||||||
>
|
>
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
<img v-if="item.path === '/communication/channel'" src="~/assets/images/hot.png" alt="火" class="absolute right--15px top--2px" />
|
<img v-if="item.path === '/communication/channel'" src="~/assets/images/hot.png" alt="火" class="absolute right-[-15px] top-[-2px]" />
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isLogin" class="flex flex-1 items-center justify-end">
|
<div v-if="isLogin" class="flex flex-1 items-center justify-end">
|
||||||
<div class="h-36px w-36px cursor-pointer border-rd-[50%] bg-[#F5F5F5] text-center line-height-44px" @click="handleUserCenter">
|
<div class="h-[36px] w-[36px] cursor-pointer border-rd-[50%] bg-[#F5F5F5] text-center flex items-center justify-center" @click="handleUserCenter">
|
||||||
<img src="~/assets/images/user.png" alt="" srcset="" class="h-19px w-17px" />
|
<img src="~/assets/images/user.png" alt="" srcset="" class="h-[19px] w-[17px]" />
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-8px h-36px w-36px cursor-pointer border-rd-[50%] text-center line-height-44px" @click="handleMessageCenter">
|
<div class="ml-[8px] h-[36px] w-[36px] cursor-pointer border-rd-[50%] text-center line-height-[44px]" @click="handleMessageCenter">
|
||||||
<el-icon size="20px" color="#999999"><BellFilled /></el-icon>
|
<el-icon size="20px" color="#999999"><BellFilled /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -30,18 +30,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import useUserStore from '~/store/user'
|
import useUserStore from '~/stores/user'
|
||||||
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: '/index' },
|
{ 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: '/communication/channel' },
|
{ name: '交流频道', path: '/channel' },
|
||||||
// { name: '牛人社区', path: '/community' },
|
// { name: '牛人社区', path: '/community' },
|
||||||
])
|
])
|
||||||
|
|
||||||
@ -52,12 +52,12 @@
|
|||||||
|
|
||||||
// 用户中心
|
// 用户中心
|
||||||
const handleUserCenter = () => {
|
const handleUserCenter = () => {
|
||||||
navigateTo('/personal/center/info')
|
navigateTo('/personal-Center/info')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 消息中心
|
// 消息中心
|
||||||
const handleMessageCenter = () => {
|
const handleMessageCenter = () => {
|
||||||
navigateTo('/personal/center/message')
|
navigateTo('/personal-Center/message-center')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@ -1,48 +1,48 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="w-100% border-b-1px border-b-[#eee] border-b-solid">
|
<div class="w-[100%] border-b-[1px] border-b-[#eee] border-b-solid">
|
||||||
<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="router.push('/index')" />
|
<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 navList" :key="item" class="nav" :class="props.active === item ? 'active' : ''" @click="handleClick(item)">{{ item }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="relative ml-30px">
|
<div class="relative ml-[30px]">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="searchQuery"
|
v-model="searchQuery"
|
||||||
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>
|
||||||
<!-- 搜索框 获取到焦点 显示热门列表 -->
|
<!-- 搜索框 获取到焦点 显示热门列表 -->
|
||||||
<div
|
<div
|
||||||
v-if="showHotList"
|
v-if="showHotList"
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
class="absolute left-16px top-42px z-100 w-276px 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 left-[16px] top-[42px] z-100 w-[276px] 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="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" />
|
<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-[19px] w-[17px] 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-[14px] 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="个人中心"
|
||||||
@ -67,10 +67,10 @@
|
|||||||
import { top } from '~/api/home/index'
|
import { top } 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 useUserStore from '~/store/user'
|
import refreshToken from '~/utils/RefreshToken'
|
||||||
|
import useUserStore from '~/stores/user'
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const { $openLogin } = useNuxtApp()
|
const app = useNuxtApp()
|
||||||
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
active: {
|
active: {
|
||||||
@ -131,22 +131,25 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 || ''}`, '_blank')
|
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 || ''}`, '_blank')
|
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 || ''}`, '_blank')
|
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) {
|
switch (item) {
|
||||||
case '首页':
|
case '首页':
|
||||||
navigateTo('/index') // 修改为在新窗口打开
|
navigateTo({ path: '/' }) // 修改为在新窗口打开
|
||||||
break
|
break
|
||||||
case '图纸':
|
case '图纸':
|
||||||
navigateTo('/drawe') // 修改为在新窗口打开
|
navigateTo('/drawe') // 修改为在新窗口打开
|
||||||
@ -164,7 +167,7 @@
|
|||||||
navigateTo('/community') // 修改为在新窗口打开
|
navigateTo('/community') // 修改为在新窗口打开
|
||||||
break
|
break
|
||||||
case '交流频道':
|
case '交流频道':
|
||||||
navigateTo('/communication/channel') // 修改为在新窗口打开
|
navigateTo('/channel') // 修改为在新窗口打开
|
||||||
break
|
break
|
||||||
case '工具箱':
|
case '工具箱':
|
||||||
navigateTo('/toolbox') // 修改为在新窗口打开
|
navigateTo('/toolbox') // 修改为在新窗口打开
|
||||||
@ -174,14 +177,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const handleLogin = () => {
|
const handleLogin = () => {
|
||||||
$openLogin()
|
app?.$openLogin() // 调用全局方法
|
||||||
}
|
}
|
||||||
const handleCommand = (command: string) => {
|
const handleCommand = (command: string) => {
|
||||||
if (command === '退出') {
|
if (command === '退出') {
|
||||||
|
clearNuxtState(['token', 'userInfo'])
|
||||||
userStore.logout()
|
userStore.logout()
|
||||||
userStore.$reset()
|
userStore.$reset()
|
||||||
} else if (command === '个人中心') {
|
} else if (command === '个人中心') {
|
||||||
navigateTo('/personal/center/info')
|
navigateTo('/personal-Center/info')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,10 +28,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="message-content">
|
<div class="message-content">
|
||||||
<div v-if="msg.msgType === 0" class="message-bubble whitespace-pre-wrap">{{ msg.content }}</div>
|
<div v-if="msg.msgType === 0" class="message-bubble whitespace-pre-wrap">{{ msg.content }}</div>
|
||||||
<div v-else-if="msg.msgType === 1" class="message-bubble max-w-50%">
|
<div v-else-if="msg.msgType === 1" class="message-bubble max-w-[50%]">
|
||||||
<img :src="msg.content" alt="图片" class="w-100%" />
|
<img :src="msg.content" alt="图片" class="w-[100%]" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="message-bubble max-w-50%">
|
<div v-else class="message-bubble max-w-[50%]">
|
||||||
{{ msg.content.split('/').pop() }}
|
{{ msg.content.split('/').pop() }}
|
||||||
</div>
|
</div>
|
||||||
<div class="message-time">{{ dayjs(msg.createTime).format('YYYY-MM-DD HH:mm:ss') }}</div>
|
<div class="message-time">{{ dayjs(msg.createTime).format('YYYY-MM-DD HH:mm:ss') }}</div>
|
||||||
@ -91,7 +91,7 @@
|
|||||||
import { upload } from '~/api/common'
|
import { upload } from '~/api/common'
|
||||||
import { sendKefuMessage, getMessagePage } from '~/api/channel/index'
|
import { sendKefuMessage, getMessagePage } from '~/api/channel/index'
|
||||||
import type { msgType, PageResultMessageRespVO } from '~/api/channel/types'
|
import type { msgType, PageResultMessageRespVO } from '~/api/channel/types'
|
||||||
import useUserStore from '~/store/user'
|
import useUserStore from '~/stores/user'
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
@ -299,6 +299,9 @@
|
|||||||
inputMessage.value = imageUrl
|
inputMessage.value = imageUrl
|
||||||
handleSend(msgType)
|
handleSend(msgType)
|
||||||
}
|
}
|
||||||
|
img.onerror = () => {
|
||||||
|
ElMessage.error('图片加载失败')
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
inputMessage.value = imageUrl
|
inputMessage.value = imageUrl
|
||||||
handleSend(msgType)
|
handleSend(msgType)
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="visible" width="800px" class="vip-dialog" align-center>
|
<el-dialog v-model="visible" width="800px" class="vip-dialog" align-center @close="handleClose">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="vip-modal-title">VIP套餐</div>
|
<div class="vip-modal-title">VIP套餐</div>
|
||||||
</template>
|
</template>
|
||||||
<div v-loading="loading" class="vip-cards">
|
<div v-loading="loading" class="vip-cards">
|
||||||
<div v-for="item in viplist" :key="item.id" class="vip-card">
|
<div v-for="item in viplist" :key="item.id" class="vip-card">
|
||||||
<div class="relative w-100% flex flex-col items-center">
|
<div class="relative! w-[100%] flex flex-col items-center">
|
||||||
<div class="vip-card-header basic">
|
<div class="vip-card-header basic">
|
||||||
<div class="vip-card-title">{{ item.name }}</div>
|
<div class="vip-card-title">{{ item.name }}</div>
|
||||||
<!-- <div class="vip-card-subtitle">中小微企业</div> -->
|
<!-- <div class="vip-card-subtitle">中小微企业</div> -->
|
||||||
@ -22,7 +22,7 @@
|
|||||||
>
|
>
|
||||||
</ul>
|
</ul>
|
||||||
<div v-if="item.qrCodeUrl" class="vip-card-qrcode">
|
<div v-if="item.qrCodeUrl" class="vip-card-qrcode">
|
||||||
<el-icon class="absolute right-0px top-0px cursor-pointer" @click="item.qrCodeUrl = ''"><Close /></el-icon>
|
<el-icon class="absolute! right-[0px] top-[0px] cursor-pointer" @click="item.qrCodeUrl = ''"><Close /></el-icon>
|
||||||
<qrcode-vue :value="item.qrCodeUrl" :size="150" level="H" />
|
<qrcode-vue :value="item.qrCodeUrl" :size="150" level="H" />
|
||||||
<div>请使用微信扫二维码</div>
|
<div>请使用微信扫二维码</div>
|
||||||
</div>
|
</div>
|
||||||
@ -41,7 +41,7 @@
|
|||||||
import type { AppPayWalletPackageRespVO } from '~/api/pay/types'
|
import type { AppPayWalletPackageRespVO } from '~/api/pay/types'
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import QrcodeVue from 'qrcode.vue'
|
import QrcodeVue from 'qrcode.vue'
|
||||||
import useUserStore from '~/store/user'
|
import useUserStore from '~/stores/user'
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
@ -133,6 +133,14 @@
|
|||||||
clearInterval(interval.value)
|
clearInterval(interval.value)
|
||||||
interval.value = undefined
|
interval.value = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 关闭弹窗 */
|
||||||
|
const handleClose = () => {
|
||||||
|
visible.value = false
|
||||||
|
// 清空任务
|
||||||
|
clearInterval(interval.value)
|
||||||
|
interval.value = undefined
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@ -153,7 +161,7 @@
|
|||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
|
||||||
padding: 24px 32px;
|
padding: 24px 32px;
|
||||||
width: 260px;
|
width: 290px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -231,5 +239,15 @@
|
|||||||
z-index: 1;
|
z-index: 1;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-dialog__header) {
|
||||||
|
.el-dialog__close {
|
||||||
|
top: -10px !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,26 +1,26 @@
|
|||||||
<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>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-item" @click="handleService">
|
<div class="button-item" @click="handleService">
|
||||||
<el-badge :is-dot="readCount" class="item">
|
<el-badge :is-dot="readCount" class="item">
|
||||||
<el-icon class="icon-item color-#10c55b!"><Service /></el-icon>
|
<el-icon class="icon-item !color-[#10c55b]"><Service /></el-icon>
|
||||||
</el-badge>
|
</el-badge>
|
||||||
<span class="button-text">客服</span>
|
<span class="button-text">客服</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-item" @click="handleSign">
|
<div class="button-item" @click="handleSign">
|
||||||
<el-icon class="icon-item color-#10c55b!"><Checked /></el-icon>
|
<el-icon class="icon-item !color-[#10c55b]"><Checked /></el-icon>
|
||||||
<span class="button-text">签到</span>
|
<span class="button-text">签到</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-item" @click="handlePublish">
|
<div class="button-item" @click="handlePublish">
|
||||||
<el-icon class="icon-item color-#C561F9!"><Promotion /></el-icon>
|
<el-icon class="icon-item !color-[#C561F9]"><Promotion /></el-icon>
|
||||||
<span class="button-text">发布</span>
|
<span class="button-text">发布</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-item mt-10px" @click="scrollToTop">
|
<div class="button-item mt-[10px]" @click="scrollToTop">
|
||||||
<el-icon class="icon-item"><Top /></el-icon>
|
<el-icon class="icon-item"><Top /></el-icon>
|
||||||
<span class="button-text">顶部</span>
|
<span class="button-text">顶部</span>
|
||||||
</div>
|
</div>
|
||||||
@ -33,9 +33,10 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import useUserStore from '~/store/user'
|
import useUserStore from '~/stores/user'
|
||||||
import { Service, Top, Promotion, Checked, Trophy } from '@element-plus/icons-vue'
|
import { Service, Top, Promotion, Checked, Trophy } from '@element-plus/icons-vue'
|
||||||
import KlService from './components/kl-service.vue'
|
import KlService from './components/kl-service.vue'
|
||||||
|
import KlVip from './components/kl-vip.vue'
|
||||||
|
|
||||||
const showVip = ref(false)
|
const showVip = ref(false)
|
||||||
const handleVip = () => {
|
const handleVip = () => {
|
||||||
@ -63,7 +64,7 @@
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 新开窗口 用router跳转 新窗口打开
|
// 新开窗口 用router跳转 新窗口打开
|
||||||
navigateTo('/upnew/drawe')
|
navigateTo('/upnew')
|
||||||
}
|
}
|
||||||
|
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
@ -87,7 +88,7 @@
|
|||||||
ElMessage.error('请先登录')
|
ElMessage.error('请先登录')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
navigateTo('/sign-page')
|
navigateTo('/sign-content')
|
||||||
}
|
}
|
||||||
|
|
||||||
const readCount = ref(false)
|
const readCount = ref(false)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<div v-if="visible" class="popup-overlay">
|
<div v-if="visible" class="popup-overlay">
|
||||||
<div class="popup-content">
|
<div class="popup-content">
|
||||||
<div class="register-container relative">
|
<div class="register-container relative">
|
||||||
<el-icon class="absolute right-0 top-0 cursor-pointer" @click="onClose()"><Close /></el-icon>
|
<el-icon class="absolute! right-0 top-0 cursor-pointer" @click="onClose()"><Close /></el-icon>
|
||||||
<!-- 左侧插图 -->
|
<!-- 左侧插图 -->
|
||||||
<div class="register-left">
|
<div class="register-left">
|
||||||
<img src="~/assets/images/login-illustration.png" alt="register" class="register-img" />
|
<img src="~/assets/images/login-illustration.png" alt="register" class="register-img" />
|
||||||
@ -58,7 +58,7 @@
|
|||||||
const { $openLogin } = useNuxtApp()
|
const { $openLogin } = useNuxtApp()
|
||||||
|
|
||||||
import REFRESHTOKEN from '~/utils/RefreshToken'
|
import REFRESHTOKEN from '~/utils/RefreshToken'
|
||||||
import useUserStore from '~/store/user'
|
import useUserStore from '~/stores/user'
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|||||||
@ -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"
|
||||||
>
|
>
|
||||||
上传图纸
|
上传图纸
|
||||||
@ -61,7 +61,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, ref } from 'vue'
|
import { onMounted, ref } from 'vue'
|
||||||
import { Search } from '@element-plus/icons-vue'
|
import { Search } from '@element-plus/icons-vue'
|
||||||
import useUserStore from '~/store/user'
|
import useUserStore from '~/stores/user'
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
|
||||||
import { top } from '~/api/home/index'
|
import { top } from '~/api/home/index'
|
||||||
@ -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(() => {
|
||||||
@ -1,36 +1,37 @@
|
|||||||
<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>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-30px box-border w-100% border border-[#EEEEEE] rounded-12px border-solid bg-[#FFFFFF] px-20px py-26px">
|
<div class="mt-[30px] box-border w-[100%] border border-[#EEEEEE] rounded-[12px] border-solid bg-[#FFFFFF] px-[20px] py-[26px]">
|
||||||
<div class="mb-14px flex items-start">
|
<div class="mb-[14px] flex items-start">
|
||||||
<div class="flex-shrink-0 text-15px text-[#333333] font-normal">{{ computType }}分类</div>
|
<div class="flex-shrink-0 text-[15px] text-[#333333] font-normal">{{ computType }}分类</div>
|
||||||
<div class="ml-30px mt--6px flex flex-wrap">
|
<div class="ml-[30px] mt-[-6px] flex flex-wrap">
|
||||||
<div
|
<div
|
||||||
v-for="(item, index) in projectTypeList"
|
v-for="(item, index) in projectTypeList"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="mb-8px mr-26px cursor-pointer rounded-15px px-15px py-6px text-14px text-[#666666] font-normal"
|
class="mb-[8px] mr-[26px] cursor-pointer rounded-[15px] px-[15px] py-[6px] text-[14px] text-[#666666] font-normal"
|
||||||
:class="item.id === query.projectType ? 'bg-#EBEEFE! !text-[#1A65FF]' : ''"
|
:class="item.id === query.projectType ? '!bg-[#ebeefe] !text-[#1A65FF]' : ''"
|
||||||
@click="handleClick(item)"
|
@click="handleClick(item)"
|
||||||
>{{ item.name }}</div
|
>{{ item.name }}</div
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-start">
|
<div class="flex items-start">
|
||||||
<div class="flex-shrink-0 text-15px text-[#333333] font-normal">软件分类</div>
|
<div class="flex-shrink-0 text-[15px] text-[#333333] font-normal">软件分类</div>
|
||||||
<div class="ml-30px mt--6px flex flex-wrap">
|
<div class="ml-[30px] mt-[-6px] flex flex-wrap">
|
||||||
<div
|
<div
|
||||||
v-for="(item, index) in editionsList"
|
v-for="(item, index) in editionsList"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="mb-8px mr-26px cursor-pointer rounded-15px px-15px py-6px text-14px text-[#666666] font-normal"
|
class="mb-[8px] mr-[26px] cursor-pointer rounded-[15px] px-[15px] py-[6px] text-[14px] text-[#666666] font-normal"
|
||||||
:class="item.id === query.editions ? '!bg-[#EBEEFE] !text-[#1A65FF]' : ''"
|
:class="item.id === query.editions ? '!bg-[#ebeefe] !text-[#1A65FF]' : ''"
|
||||||
@click="query.editions = item.id"
|
@click="query.editions = item.id"
|
||||||
>{{ item.name }}</div
|
>
|
||||||
|
{{ item.name }}</div
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -53,6 +54,7 @@
|
|||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import { parent } from '~/api/upnew/index'
|
import { parent } from '~/api/upnew/index'
|
||||||
import type { pageReq } from '~/api/upnew/types'
|
import type { pageReq } from '~/api/upnew/types'
|
||||||
|
import { getDictTree } from '~/api/home/index'
|
||||||
import { ArrowRight } from '@element-plus/icons-vue'
|
import { ArrowRight } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -73,73 +75,116 @@
|
|||||||
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: breadList } = await useAsyncData(
|
||||||
if (type === 'init' && level.value.find((c: any) => c.isChildren)) {
|
`breadList-${props.type}-${props.id}-${query.value.projectType}-${Date.now()}`,
|
||||||
return level.value[level.value.length - 2].id || '' // 获取最后一个元素的 id 或 defaul
|
async () => {
|
||||||
}
|
const res = await getDictTree({ type: 1, id: query.value.projectType })
|
||||||
return level.value[level.value.length - 1].id || '' // 获取最后一个元素的 id 或 defaul
|
const all = [
|
||||||
}
|
{
|
||||||
return '0'
|
id: -1,
|
||||||
|
name: props.type === 1 ? '图纸库' : props.type === 3 ? '模型库' : '文本库',
|
||||||
|
isChildren: false,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const arr = [...res.data, ...all]
|
||||||
|
return arr.reverse()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true,
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
const projectTypeList = ref<any>([])
|
console.log('breadList', breadList);
|
||||||
|
|
||||||
|
// const projectTypeList = ref<any>([])
|
||||||
/** 获取分类下拉框 */
|
/** 获取分类下拉框 */
|
||||||
const getParent = (type?: string) => {
|
// const getParent = (type?: string) => {
|
||||||
parent({
|
// parent({
|
||||||
type: 1,
|
// type: 1,
|
||||||
// @ts-ignore
|
// parentId: handleParentId(type),
|
||||||
parentId: handleParentId(type),
|
// }).then((res) => {
|
||||||
}).then((res) => {
|
// if (Array.isArray(res.data)) {
|
||||||
if (Array.isArray(res.data)) {
|
// // projectTypeList.value = [...[{ id: handleParentId(type), name: '全部' }], ...res.data]
|
||||||
projectTypeList.value = [...[{ id: handleParentId(type), name: '全部' }], ...res.data]
|
// }
|
||||||
}
|
// })
|
||||||
})
|
// }
|
||||||
}
|
// getParent('init')
|
||||||
getParent('init')
|
|
||||||
|
|
||||||
/** 版本 */
|
/** 版本 */
|
||||||
const editionsList = ref<any>([])
|
// const editionsList = ref<any>([])
|
||||||
const getEditionsList = () => {
|
// const getEditionsList = () => {
|
||||||
parent({
|
// parent({
|
||||||
type: 2,
|
// type: 2,
|
||||||
parentId: 0,
|
// parentId: 0,
|
||||||
}).then((res) => {
|
// }).then((res) => {
|
||||||
if (Array.isArray(res.data)) {
|
// if (Array.isArray(res.data)) {
|
||||||
editionsList.value = [...[{ id: '', name: '全部' }], ...res.data]
|
// // editionsList.value = [...[{ id: '', name: '全部' }], ...res.data]
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// getEditionsList()
|
||||||
|
|
||||||
|
/**获取分类下拉框 */
|
||||||
|
const { data: projectTypeList } = await useAsyncData(
|
||||||
|
`projectType-draw-${props.type}-${query.value.projectType}`,
|
||||||
|
async () => {
|
||||||
|
let parentId: any = '0'
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
const res = await parent({ type: 1, parentId: parentId })
|
||||||
|
const all = [{ id: parentId === '0' ? '-1' : parentId, name: '全部' }]
|
||||||
|
return [...all, ...res.data]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/** 版本 */
|
||||||
|
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]
|
||||||
})
|
})
|
||||||
}
|
|
||||||
getEditionsList()
|
|
||||||
|
|
||||||
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()
|
||||||
}
|
// 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()
|
||||||
|
// refresh()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
<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-[10px] text-[16px] text-[#999999] font-normal"
|
||||||
>共<span class="color-#1A65FF">{{ result.total }}</span
|
>共<span class="color-[#1A65FF]">{{ result?.total }}</span
|
||||||
>个筛选结果</div
|
>个筛选结果</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">
|
||||||
<CardPicture :item-info="item" />
|
<CardPicture :item-info="item" />
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-empty v-if="!result.list.length" :image="emptyImg"></el-empty>
|
<el-empty v-if="!result?.list.length" :image="emptyImg"></el-empty>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -26,14 +26,14 @@
|
|||||||
const query = defineModel<pageReq>('modelValue', {
|
const query = defineModel<pageReq>('modelValue', {
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
const result = defineModel<pageRes>('result', {
|
const result = defineModel<pageRes| null>('result', {
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const tabBar = ref([
|
const tabBar = ref([
|
||||||
{
|
{
|
||||||
label: '模型推荐',
|
label: '模型推荐',
|
||||||
value: '',
|
value: -1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '原创模型',
|
label: '原创模型',
|
||||||
25
components/seo-head/index.vue
Normal file
25
components/seo-head/index.vue
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const props = defineProps({
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
default: '图夕夕-世界图纸 夕夕共享',
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
default: '图夕夕是一家图纸素材分享交易平台,提供AutoCAD/ProE/Creo/CATIA/UG/inventor/CAXA/等建筑图纸的素材下载及免费教程。',
|
||||||
|
},
|
||||||
|
keywords: {
|
||||||
|
type: String,
|
||||||
|
default: '图纸,图纸下载,设计素材,图纸大全,设计图纸,,工程图纸,cad图纸',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
useHead({
|
||||||
|
title: `${props.title} - 图夕夕`,
|
||||||
|
meta: [
|
||||||
|
{ name: 'description', content: `${props.description}`},
|
||||||
|
{ name: 'keywords', content: props.keywords },
|
||||||
|
],
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@ -1,17 +1,17 @@
|
|||||||
<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-[10px] text-[16px] text-[#999999] font-normal"
|
||||||
>共<span class="color-#1A65FF">{{ result.total }}</span
|
>共<span class="color-[#1A65FF]">{{ result?.total }}</span
|
||||||
>个筛选结果</div
|
>个筛选结果</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">
|
||||||
<CardPicture :item-info="item" />
|
<CardPicture :item-info="item" />
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-empty v-if="!result.list.length" :image="emptyImg"></el-empty>
|
<el-empty v-if="!result?.list?.length" :image="emptyImg"></el-empty>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -27,14 +27,14 @@
|
|||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const result = defineModel<pageRes>('result', {
|
const result = defineModel<pageRes | null>('result', {
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const tabBar = ref([
|
const tabBar = ref([
|
||||||
{
|
{
|
||||||
label: '文本推荐',
|
label: '文本推荐',
|
||||||
value: '',
|
value: -1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '原创文本',
|
label: '原创文本',
|
||||||
34
composables/states.ts
Normal file
34
composables/states.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/** 用户信息 **/
|
||||||
|
export const useToken = () =>
|
||||||
|
useState<string>('token', () => {
|
||||||
|
const token = useCookie<string | undefined>('token');
|
||||||
|
return token.value ? token.value : '';
|
||||||
|
});
|
||||||
|
|
||||||
|
type UserInfo = {
|
||||||
|
nickname: string,
|
||||||
|
avatar: string,
|
||||||
|
mobile: string,
|
||||||
|
id: number | undefined,
|
||||||
|
vipLevel: number | undefined,
|
||||||
|
sex: number | undefined,
|
||||||
|
}
|
||||||
|
/** 用户信息 */
|
||||||
|
export const useUserInfo = () => useState<UserInfo>('userInfo', () => {
|
||||||
|
return {
|
||||||
|
nickname: '',
|
||||||
|
avatar: '',
|
||||||
|
mobile: '',
|
||||||
|
id: undefined,
|
||||||
|
vipLevel: undefined,
|
||||||
|
sex: undefined,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 热门数据 */
|
||||||
|
export const useHotMeg = () => useState<any>('hotMsg', () => {
|
||||||
|
return {
|
||||||
|
projectType:'',
|
||||||
|
projectTypeTop: ''
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -1,4 +1,5 @@
|
|||||||
import { isArray } from "~/utils/utils";
|
import { isArray } from "~/utils/utils";
|
||||||
|
// 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];
|
||||||
@ -15,12 +16,11 @@ const useClientRequest = async <T = unknown>(
|
|||||||
onRequest({ options }) {
|
onRequest({ options }) {
|
||||||
options.headers = options.headers || 'application/json';
|
options.headers = options.headers || 'application/json';
|
||||||
if (token.value) {
|
if (token.value) {
|
||||||
// @ts-ignore
|
options.headers.set("Authorization", `Bearer ${token.value}`);
|
||||||
options.headers["authorization"] = "Bearer " + token.value;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onResponse({ response }) {
|
onResponse({ response }) {
|
||||||
if (+response.status === 200 && +response._data.code !== 200) {
|
if (+response.status === 200 && +response._data.code !== 0) {
|
||||||
ElMessage.error(response._data.msg);
|
ElMessage.error(response._data.msg);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -71,5 +71,7 @@ const useClientRequest = async <T = unknown>(
|
|||||||
body?: any,
|
body?: any,
|
||||||
config?: Omit<FetchOptions, 'method' | 'body'>
|
config?: Omit<FetchOptions, 'method' | 'body'>
|
||||||
): Promise<T> => {
|
): Promise<T> => {
|
||||||
|
console.log({ ...config, method: 'PUT', body });
|
||||||
|
|
||||||
return useClientRequest<T>(endpoint, { ...config, method: 'PUT', body })
|
return useClientRequest<T>(endpoint, { ...config, method: 'PUT', body })
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,74 +1,51 @@
|
|||||||
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'
|
||||||
|
|
||||||
const useServerRequest = async <T>(
|
const useServerRequest = async <T>(url: string, opts?: UseFetchOptions<T, unknown>) => {
|
||||||
url: string,
|
const token = useToken()
|
||||||
opts?: UseFetchOptions<T, unknown>
|
const runtimeConfig = useRuntimeConfig()
|
||||||
) => {
|
|
||||||
const token = useCookie<string | undefined>("token");
|
|
||||||
const runtimeConfig = useRuntimeConfig();
|
|
||||||
|
|
||||||
const defaultOptions: UseFetchOptions<unknown> = {
|
const defaultOptions: UseFetchOptions<unknown> = {
|
||||||
baseURL: runtimeConfig.public.apiBase,
|
baseURL: runtimeConfig.public.apiBase,
|
||||||
onRequest({ options }) {
|
onRequest({ options }) {
|
||||||
options.headers = options.headers || "application/json";
|
options.headers = options.headers || {}
|
||||||
if (token.value) {
|
if (token.value) {
|
||||||
// @ts-ignore
|
options.headers.set('Authorization', `Bearer ${token.value}`)
|
||||||
options.headers["authorization"] = "Bearer " + token.value;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onResponse({ response }) {
|
onResponse({ response }) {
|
||||||
if (+response.status === 200 && +response._data.code !== 200) {
|
if (+response.status === 200 && +response._data.code !== 0) {
|
||||||
process.client && ElMessage.error(response._data.msg);
|
process.client && ElMessage.error(response._data.msg)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onResponseError({ response }) {
|
onResponseError({ response }) {
|
||||||
process.client &&
|
process.client && ElMessage.error(isArray(response._data.data.msg) ? response._data.data.msg[0] : response._data.data.msg)
|
||||||
ElMessage.error(
|
|
||||||
isArray(response._data.data.msg)
|
|
||||||
? response._data.data.msg[0]
|
|
||||||
: response._data.data.msg
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
|
|
||||||
// return useFetch<T>(url, { ...defaultOptions, ...opts } as any);
|
// return useFetch<T>(url, { ...defaultOptions, ...opts } as any);
|
||||||
// 明确转换返回类型
|
// 明确转换返回类型
|
||||||
const response = await useFetch<T>(url, { ...defaultOptions, ...opts, key: 'unique-key-' + Date.now(), } as any);
|
const response = await useFetch<T>(url, { ...defaultOptions, ...opts } as any)
|
||||||
return response.data.value as unknown as T;
|
return response.data.value as unknown as T
|
||||||
};
|
}
|
||||||
|
|
||||||
// GET请求
|
// GET请求
|
||||||
export const get = <T = unknown>(
|
export const get = <T = unknown>(endpoint: string, config?: Omit<FetchOptions, 'method'>): Promise<T> => {
|
||||||
endpoint: string,
|
|
||||||
config?: Omit<FetchOptions, 'method'>
|
|
||||||
): Promise<T> => {
|
|
||||||
return useServerRequest<T>(endpoint, { ...config, method: 'GET' })
|
return useServerRequest<T>(endpoint, { ...config, method: 'GET' })
|
||||||
}
|
}
|
||||||
|
|
||||||
// POST请求
|
// POST请求
|
||||||
export const post = <T = unknown>(
|
export const post = <T = unknown>(endpoint: string, body?: any, config?: Omit<FetchOptions, 'method' | 'body'>): Promise<T> => {
|
||||||
endpoint: string,
|
|
||||||
body?: any,
|
|
||||||
config?: Omit<FetchOptions, 'method' | 'body'>
|
|
||||||
): Promise<T> => {
|
|
||||||
return useServerRequest<T>(endpoint, { ...config, method: 'POST', body })
|
return useServerRequest<T>(endpoint, { ...config, method: 'POST', body })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DELETE请求
|
||||||
// DELETE请求
|
export const del = <T = unknown>(endpoint: string, config?: Omit<FetchOptions, 'method'>): Promise<T> => {
|
||||||
export const del = <T = unknown>(
|
|
||||||
endpoint: string,
|
|
||||||
config?: Omit<FetchOptions, 'method'>
|
|
||||||
): Promise<T> => {
|
|
||||||
return useServerRequest<T>(endpoint, { ...config, method: 'DELETE' })
|
return useServerRequest<T>(endpoint, { ...config, method: 'DELETE' })
|
||||||
}
|
}
|
||||||
|
|
||||||
// PUT请求
|
// PUT请求
|
||||||
export const put = <T = unknown>(
|
export const put = <T = unknown>(endpoint: string, body?: any, config?: Omit<FetchOptions, 'method' | 'body'>): Promise<T> => {
|
||||||
endpoint: string,
|
|
||||||
body?: any,
|
|
||||||
config?: Omit<FetchOptions, 'method' | 'body'>
|
|
||||||
): Promise<T> => {
|
|
||||||
return useServerRequest<T>(endpoint, { ...config, method: 'PUT', body })
|
return useServerRequest<T>(endpoint, { ...config, method: 'PUT', body })
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,8 +10,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import KlFooter from '~/layout/kl-footer/index.vue'
|
|
||||||
import KlQuickMenu from '~/components/kl-quick-menu/index.vue'
|
import KlQuickMenu from '~/components/kl-quick-menu/index.vue'
|
||||||
|
import KlFooter from '~/components/kl-footer/index.vue'
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
0
layouts/m.vue
Normal file
0
layouts/m.vue
Normal file
22
middleware/auth.global.ts
Normal file
22
middleware/auth.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('/m')
|
||||||
|
|
||||||
|
console.log(isMobile, isRouterMobile);
|
||||||
|
|
||||||
|
// 移动端并且 不是/m开头路由
|
||||||
|
if (isMobile && !isRouterMobile) {
|
||||||
|
return navigateTo(`/m`)
|
||||||
|
}
|
||||||
|
// 不是移动端 是/m开头路由
|
||||||
|
if (!isMobile && isRouterMobile) {
|
||||||
|
return navigateTo(`/`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
@ -1 +0,0 @@
|
|||||||
// 从微信登录重定向到项目 需要获取code值
|
|
||||||
144
nuxt.config.ts
144
nuxt.config.ts
@ -1,18 +1,26 @@
|
|||||||
// 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,
|
||||||
// },
|
// },
|
||||||
|
|
||||||
devtools: {
|
devtools: {
|
||||||
enabled: process.env.NODE_ENV === "development",
|
enabled: process.env.NODE_ENV === 'development',
|
||||||
},
|
},
|
||||||
debug: process.env.NODE_ENV === "development", // 开启详细调试日志
|
debug: process.env.NODE_ENV === 'development', // 开启详细调试日志
|
||||||
|
|
||||||
ssr: true,
|
ssr: true,
|
||||||
modules: ["@unocss/nuxt", "@pinia/nuxt", "@element-plus/nuxt"],
|
modules: ['@unocss/nuxt', '@pinia/nuxt', '@element-plus/nuxt', 'pinia-plugin-persistedstate/nuxt'],
|
||||||
css: ["@unocss/reset/tailwind.css", "element-plus/dist/index.css"],
|
unocss: {
|
||||||
|
nuxtLayers: true,
|
||||||
|
},
|
||||||
|
elementPlus: {
|
||||||
|
importStyle: 'scss', // 或 'css',确保样式被全局导入
|
||||||
|
themes: ['dark'], // 按需配置主题
|
||||||
|
},
|
||||||
|
css: ['element-plus/dist/index.css', '~/assets/scss/app.scss'],
|
||||||
vite: {
|
vite: {
|
||||||
css: {
|
css: {
|
||||||
preprocessorOptions: {
|
preprocessorOptions: {
|
||||||
@ -22,77 +30,91 @@ export default defineNuxtConfig({
|
|||||||
},
|
},
|
||||||
postcss: {
|
postcss: {
|
||||||
plugins: [
|
plugins: [
|
||||||
// postCssPxToRem({
|
postcsspxtoviewport({
|
||||||
// rootValue: 16, // 结果为:设计稿元素尺寸/16,比如元素宽320px,最终页面会换算成 20rem
|
unitToConvert: 'px', // 要转化的单位
|
||||||
// mediaQuery: false, //(布尔值)允许在媒体查询中转换px。
|
viewportWidth: 750, // UI设计稿的宽度
|
||||||
// // exclude: /node_modules/, //node_modules目录下样式全部不转义
|
unitPrecision: 6, // 转换后的精度,即小数点位数
|
||||||
// propList: ['*'] //需要做转化处理的属性如`hight`、`width`、`margin`等,`*`表示全部
|
propList: ['*'], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换
|
||||||
// })
|
viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认vw
|
||||||
|
fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认vw
|
||||||
|
selectorBlackList: ['el-'], // 指定不转换为视窗单位的类名,例如van-(vantUI组件),
|
||||||
|
minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换
|
||||||
|
mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
|
||||||
|
replace: true, // 是否转换后直接更换属性值
|
||||||
|
exclude: [/node_modules/, /^(?!.*\/pages\/m\/).*$/], // 排除node_modules和非pages/m目录下的文件
|
||||||
|
landscape: false, // 是否处理横屏情况
|
||||||
|
// 只转换pages下的m文件
|
||||||
|
include: [/pages\/m/],
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
include: ["naive-ui"],
|
include: ['naive-ui'],
|
||||||
},
|
},
|
||||||
// 生产环境构建优化
|
// 生产环境构建优化
|
||||||
build: {
|
build: {
|
||||||
// 生产环境移除 console 和 debugger
|
// 生产环境移除 console 和 debugger
|
||||||
minify: "esbuild",
|
minify: 'esbuild',
|
||||||
target: "es2020",
|
target: 'es2020',
|
||||||
},
|
},
|
||||||
esbuild: {
|
esbuild: {
|
||||||
// 生产环境下移除所有 console 语句和 debugger
|
// 生产环境下移除所有 console 语句和 debugger
|
||||||
drop:
|
drop: process.env.NODE_ENV === 'production' ? ['console', 'debugger'] : [],
|
||||||
process.env.NODE_ENV === "production" ? ["console", "debugger"] : [],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
// 页面过渡配置
|
// 页面过渡配置
|
||||||
app: {
|
app: {
|
||||||
pageTransition: {
|
// pageTransition: {
|
||||||
name: "page",
|
// name: "page",
|
||||||
mode: "out-in",
|
// mode: "out-in",
|
||||||
duration: 400,
|
// duration: 400,
|
||||||
},
|
// },
|
||||||
layoutTransition: {
|
// layoutTransition: {
|
||||||
name: "layout",
|
// name: "default",
|
||||||
mode: "out-in",
|
// mode: "out-in",
|
||||||
duration: 400,
|
// duration: 400,
|
||||||
},
|
// },
|
||||||
head: {
|
head: {
|
||||||
title: "xlCig - 专业PC硬件产品和装机服务",
|
title: '图夕夕-世界图纸 夕夕共享',
|
||||||
htmlAttrs: {
|
htmlAttrs: {
|
||||||
lang: "en",
|
lang: 'en',
|
||||||
},
|
},
|
||||||
meta: [
|
meta: [
|
||||||
{ charset: "utf-8" },
|
{ charset: 'utf-8' },
|
||||||
{ name: "viewport", content: "width=device-width, initial-scale=1" },
|
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
|
||||||
{
|
{
|
||||||
name: "description",
|
name: 'description',
|
||||||
content: "专业的PC硬件产品和装机建议,助您打造梦想中的高性能电脑",
|
content: '图夕夕是一家图纸素材分享交易平台,提供AutoCAD/ProE/Creo/CATIA/UG/inventor/CAXA/等建筑图纸的素材下载及免费教程。',
|
||||||
},
|
},
|
||||||
{ name: "keywords", content: "xlCig,PC硬件,电脑配置,显卡,CPU,装机" },
|
{ name: 'keywords', content: '图纸,图纸下载,设计素材,图纸大全,设计图纸,,工程图纸,cad图纸' },
|
||||||
{ name: "author", content: "xlCig" },
|
{ name: 'author', content: '图夕夕' },
|
||||||
// 百度站点验证
|
|
||||||
{ name: "baidu-site-verification", content: "codeva-2z90c1PlRw" },
|
|
||||||
// SEO meta tags
|
// SEO meta tags
|
||||||
{ property: "og:title", content: "xlCig - 专业PC硬件产品和装机服务" },
|
// {
|
||||||
{
|
// property: 'og:title',
|
||||||
property: "og:description",
|
// content: '图纸,图纸下载,设计素材,图纸大全,设计图纸,,工程图纸,cad图纸',
|
||||||
content: "专业的PC硬件产品和装机建议,助您打造梦想中的高性能电脑",
|
// },
|
||||||
},
|
// {
|
||||||
{ property: "og:type", content: "website" },
|
// property: 'og:description',
|
||||||
{ property: "og:url", content: "https://www.xlcig.cn" },
|
// content: '图夕夕是一家图纸素材分享交易平台,提供AutoCAD/ProE/Creo/CATIA/UG/inventor/CAXA/等建筑图纸的素材下载及免费教程。',
|
||||||
{ property: "og:site_name", content: "xlCig" },
|
// },
|
||||||
{ name: "theme-color", content: "#00f5ff" },
|
// { property: 'og:type', content: 'website' },
|
||||||
// robots meta
|
// { property: 'og:url', content: 'https://www.xlcig.cn' },
|
||||||
{ name: "robots", content: "index, follow" },
|
// { property: 'og:site_name', content: 'xlCig' },
|
||||||
|
// { name: 'theme-color', content: '#00f5ff' },
|
||||||
|
// // robots meta
|
||||||
|
// { name: 'robots', content: 'index, follow' },
|
||||||
],
|
],
|
||||||
link: [
|
link: [
|
||||||
{ rel: "icon", type: "image/png", href: "/logo.png" },
|
{ rel: 'icon', type: 'image/x-icon', href: '/favicon2.ico' },
|
||||||
{ rel: "apple-touch-icon", sizes: "180x180", href: "/logo.png" },
|
{ rel: 'stylesheet', type: 'text/css', href: 'https://unpkg.com/swiper@8/swiper-bundle.css' },
|
||||||
{ rel: "icon", type: "image/png", sizes: "32x32", href: "/logo.png" },
|
],
|
||||||
{ rel: "icon", type: "image/png", sizes: "16x16", href: "/logo.png" },
|
script: [
|
||||||
|
{
|
||||||
|
type: 'text/javascript',
|
||||||
|
src: 'https://unpkg.com/swiper@8/swiper-bundle.js',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -103,18 +125,28 @@ export default defineNuxtConfig({
|
|||||||
apiBase: 'https://tuxixi.net',
|
apiBase: 'https://tuxixi.net',
|
||||||
|
|
||||||
// 应用信息
|
// 应用信息
|
||||||
appName: "xlCig",
|
appName: 'xlCig',
|
||||||
appVersion: "1.0.0",
|
appVersion: '1.0.0',
|
||||||
|
|
||||||
// 调试模式
|
// 调试模式
|
||||||
debug: process.env.NODE_ENV === "development",
|
debug: process.env.NODE_ENV === 'development',
|
||||||
|
|
||||||
// 环境标识
|
// 环境标识
|
||||||
environment: process.env.NODE_ENV || "development",
|
environment: process.env.NODE_ENV || 'development',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
build: {
|
build: {
|
||||||
transpile: ["vueuc", "@css-render/vue3-ssr","@unocss"],
|
transpile: ['vueuc', '@css-render/vue3-ssr', '@tinymce/tinymce-vue', 'tinymce'],
|
||||||
},
|
},
|
||||||
});
|
plugins: [
|
||||||
|
// 在这里引入插件
|
||||||
|
{
|
||||||
|
src: '~/plugins/wang-editor',
|
||||||
|
mode: 'client',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
piniaPluginPersistedstate: {
|
||||||
|
storage: 'localStorage',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|||||||
12
package.json
12
package.json
@ -12,15 +12,16 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxtjs/axios": "^5.13.6",
|
"@nuxtjs/axios": "^5.13.6",
|
||||||
"@pinia/nuxt": "^0.11.2",
|
"@pinia/nuxt": "^0.11.2",
|
||||||
"@tinymce/tinymce-vue": "^6.3.0",
|
"@wangeditor/editor": "^5.1.23",
|
||||||
"@types/tinymce": "^5.5.0",
|
"@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",
|
||||||
"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",
|
||||||
"tinymce": "^8.0.2",
|
"postcss-px-to-viewport": "^1.1.1",
|
||||||
|
"qrcode.vue": "^3.6.0",
|
||||||
"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",
|
||||||
@ -29,8 +30,13 @@
|
|||||||
"packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610",
|
"packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@element-plus/nuxt": "^1.1.4",
|
"@element-plus/nuxt": "^1.1.4",
|
||||||
|
"@pinia-plugin-persistedstate/nuxt": "^1.2.1",
|
||||||
|
"@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",
|
||||||
"sass": "^1.90.0",
|
"sass": "^1.90.0",
|
||||||
"unocss": "^66.4.2"
|
"unocss": "^66.4.2"
|
||||||
}
|
}
|
||||||
|
|||||||
99
pages/channel/[channelId]/[pageNo].vue
Normal file
99
pages/channel/[channelId]/[pageNo].vue
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 导航 -->
|
||||||
|
<KlNavTab active="交流频道" />
|
||||||
|
<div class="ma-auto mt-[30px] w-[1440px] flex">
|
||||||
|
<LeftContent v-model="pageReq.channelId" v-model:channelIdList="channelIdList"></LeftContent>
|
||||||
|
<RightContent v-model="pageRes" v-model:lun-tan-res="lunTanRes" v-model:page-no="pageReq.pageNo" @update-page-no="handleUpdatePageNo"></RightContent>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import KlNavTab from '~/components/kl-nav-tab/index.vue'
|
||||||
|
import LeftContent from '../components/LeftContent.vue'
|
||||||
|
import RightContent from '../components/RightContent.vue'
|
||||||
|
import { page, getChannelLunTanDetail, list } from '~/api/channel/index'
|
||||||
|
import { reactive, watch, ref } from 'vue'
|
||||||
|
import type { TpageRes, ChannelRespVO } from '~/api/channel/types'
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const channelId = computed(() => (route.params.channelId as string) || '')
|
||||||
|
const pageNo = computed(() => Number(route.params.pageNo) || 1)
|
||||||
|
|
||||||
|
const pageReq = reactive({
|
||||||
|
pageNo: pageNo.value,
|
||||||
|
pageSize: 10,
|
||||||
|
channelId: channelId.value, // 频道ID
|
||||||
|
})
|
||||||
|
// const pageRes = reactive<TpageRes>({
|
||||||
|
// list: [],
|
||||||
|
// total: 0,
|
||||||
|
// })
|
||||||
|
|
||||||
|
// 获取频道列表
|
||||||
|
const { data: channelIdList } = await useAsyncData(`prod-api/app-api/business/channel/list-${Date.now()}`, async () => {
|
||||||
|
const res = await list()
|
||||||
|
return res.data as any[]
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log(channelIdList)
|
||||||
|
|
||||||
|
// 获取第一个论坛详情
|
||||||
|
// if (!channelIdList.value?.length) return
|
||||||
|
const { data: lunTanRes, execute: refreshLunTanDetail } = await useAsyncData(
|
||||||
|
`prod-api/app-api/business/channel/detail-${Date.now()}`,
|
||||||
|
async () => {
|
||||||
|
if (!channelId.value) return null // 无参数时不请求
|
||||||
|
const res = await getChannelLunTanDetail({
|
||||||
|
id: channelId.value,
|
||||||
|
})
|
||||||
|
return res.data as ChannelRespVO
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const { data: pageRes, refresh: getPage } = await useAsyncData(`prod-api/app-api/business/posts/page-${Date.now()}`, async () => {
|
||||||
|
const res = await page(pageReq)
|
||||||
|
return res.data as TpageRes
|
||||||
|
})
|
||||||
|
// 获得频道帖子分页
|
||||||
|
// const getPage = () => {
|
||||||
|
// page(pageReq).then((res) => {
|
||||||
|
// pageRes.list = res.data.list
|
||||||
|
// pageRes.total = res.data.total
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// getPage()
|
||||||
|
|
||||||
|
const handleUpdatePageNo = (pageNo: number) => {
|
||||||
|
pageReq.pageNo = pageNo
|
||||||
|
navigateTo(`/channel/${channelId.value}/${pageNo}`)
|
||||||
|
// getPage()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取论坛详情
|
||||||
|
// const lunTanRes = ref({} as ChannelRespVO)
|
||||||
|
// const getLunTanDetaiil = (val: string) => {
|
||||||
|
// getChannelLunTanDetail({
|
||||||
|
// id: val,
|
||||||
|
// }).then((res) => {
|
||||||
|
// lunTanRes.value = res.data
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
// watch(
|
||||||
|
// () => channelId.value,
|
||||||
|
// (val) => {
|
||||||
|
// if (val) {
|
||||||
|
// // 更新分页请求的channelId
|
||||||
|
// pageReq.channelId = val
|
||||||
|
// // 重新请求分页数据和论坛详情
|
||||||
|
// getPage()
|
||||||
|
// refreshLunTanDetail() // 刷新论坛详情
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
@ -4,24 +4,24 @@
|
|||||||
<!-- Logo and Title Section -->
|
<!-- Logo and Title Section -->
|
||||||
<div class="logo-title-section">
|
<div class="logo-title-section">
|
||||||
<div class="logo">
|
<div class="logo">
|
||||||
<img :src="lunTanRes.channelIcon" alt="JRS Logo" />
|
<img :src="lunTanRes?.channelIcon" alt="JRS Logo" />
|
||||||
</div>
|
</div>
|
||||||
<div class="title-section">
|
<div class="title-section">
|
||||||
<h1 class="main-title">#{{ lunTanRes.channelTitle }}</h1>
|
<h1 class="main-title">#{{ lunTanRes?.channelTitle }}</h1>
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
<el-button v-if="!lunTanRes.isFollow" type="danger" class="subscribe-btn" @click="handleFollow"
|
<el-button v-if="!lunTanRes?.isFollow" type="danger" class="subscribe-btn" @click="handleFollow"
|
||||||
><el-icon class="mr-4px color-#fff!"><Plus /></el-icon> 关注
|
><el-icon class="mr-[4px] color-[#fff!]"><Plus /></el-icon> 关注
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button v-else type="danger" class="subscribe-btn" @click="handleUnfollow"> 取消关注 </el-button>
|
<el-button v-else type="danger" class="subscribe-btn" @click="handleUnfollow"> 取消关注 </el-button>
|
||||||
<el-button type="danger" class="post-btn" @click="handleClick">
|
<el-button type="danger" class="post-btn" @click="handleClick">
|
||||||
<el-icon class="mr-4px color-#fff!"><EditPen /></el-icon> 发帖
|
<el-icon class="mr-[4px] color-[#fff!]"><EditPen /></el-icon> 发帖
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Channel Info -->
|
<!-- Channel Info -->
|
||||||
<div class="channel-info">
|
<div class="channel-info">
|
||||||
<span class="info-item">话题介绍</span>
|
<span class="info-item">话题介绍</span>
|
||||||
<span class="info-item">{{ lunTanRes.channelProfile }}</span>
|
<span class="info-item">{{ lunTanRes?.channelProfile }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Stats -->
|
<!-- Stats -->
|
||||||
@ -32,20 +32,20 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="stats-item">
|
<div class="stats-item">
|
||||||
<span class="stats-label">关注人数</span>
|
<span class="stats-label">关注人数</span>
|
||||||
<span class="stats-value"><i class="el-icon-arrow-up"></i> {{ lunTanRes.followCount }}人</span>
|
<span class="stats-value"><i class="el-icon-arrow-up"></i> {{ lunTanRes?.followCount }}人</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="stats-item">
|
<div class="stats-item">
|
||||||
<span class="stats-label">当前有</span>
|
<span class="stats-label">当前有</span>
|
||||||
<span class="stats-value"><i class="el-icon-arrow-up"></i> {{ lunTanRes.chatUserCount }}人聊天</span>
|
<span class="stats-value"><i class="el-icon-arrow-up"></i> {{ lunTanRes?.chatUserCount }}人聊天</span>
|
||||||
<span class="stats-value ml-2px cursor-pointer color-#1a65ff!" @click="handleChat">立即加入</span>
|
<span class="stats-value ml-[2px] cursor-pointer !color-[#1a65ff]" @click="handleChat">立即加入</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tags -->
|
<!-- Tags -->
|
||||||
<div class="channel-tags">
|
<div class="channel-tags">
|
||||||
<span class="tag-label">标签:</span>
|
<span class="tag-label">标签:</span>
|
||||||
<span v-for="(item, index) in lunTanRes.hotTags" :key="index" class="tag-item"
|
<span v-for="(item, index) in lunTanRes?.hotTags" :key="index" class="tag-item"
|
||||||
>{{ item }}{{ index === lunTanRes.hotTags.length - 1 ? '' : '、' }}</span
|
>{{ item }}{{ index === lunTanRes!.hotTags.length - 1 ? '' : '、' }}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -55,9 +55,9 @@
|
|||||||
<ChatPage
|
<ChatPage
|
||||||
v-if="isChat"
|
v-if="isChat"
|
||||||
v-model:is-chat="isChat"
|
v-model:is-chat="isChat"
|
||||||
:chat-title="lunTanRes.channelTitle"
|
:chat-title="lunTanRes!.channelTitle"
|
||||||
:chat-description="lunTanRes.channelProfile"
|
:chat-description="lunTanRes!.channelProfile"
|
||||||
:channel-id="lunTanRes.channelId"
|
:channel-id="lunTanRes!.channelId"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -68,28 +68,40 @@
|
|||||||
import type { ChannelRespVO } from '~/api/channel/types'
|
import type { ChannelRespVO } from '~/api/channel/types'
|
||||||
import { createChannelFollow, deleteChannelFollow } from '~/api/channel/index'
|
import { createChannelFollow, deleteChannelFollow } from '~/api/channel/index'
|
||||||
import ChatPage from '~/pages/chat-page/index.vue'
|
import ChatPage from '~/pages/chat-page/index.vue'
|
||||||
import useUserStore from '~/store/user'
|
import useUserStore from '~/stores/user'
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
|
||||||
const lunTanRes = defineModel<ChannelRespVO>('modelValue', {
|
const lunTanRes = defineModel<ChannelRespVO | null>('modelValue', {
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
window.open('/channel/create?channelId=' + lunTanRes.value.channelId, '_blank')
|
if (!userStore.token) {
|
||||||
|
ElMessage.warning('请先登录')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
navigateTo('/channel/create?channelId=' + lunTanRes.value?.channelId)
|
||||||
}
|
}
|
||||||
const handleFollow = () => {
|
const handleFollow = () => {
|
||||||
createChannelFollow({ channelId: lunTanRes.value.channelId }).then((res) => {
|
if (!userStore.token) {
|
||||||
|
ElMessage.warning('请先登录')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
createChannelFollow({ channelId: lunTanRes.value!.channelId }).then((res) => {
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
lunTanRes.value.isFollow = true
|
lunTanRes.value!.isFollow = true
|
||||||
ElMessage.success('关注成功')
|
ElMessage.success('关注成功')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const handleUnfollow = () => {
|
const handleUnfollow = () => {
|
||||||
deleteChannelFollow({ channelId: lunTanRes.value.channelId }).then((res) => {
|
if (!userStore.token) {
|
||||||
|
ElMessage.warning('请先登录')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
deleteChannelFollow({ channelId: lunTanRes.value!.channelId }).then((res) => {
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
lunTanRes.value.isFollow = false
|
lunTanRes.value!.isFollow = false
|
||||||
ElMessage.success('取消关注成功')
|
ElMessage.success('取消关注成功')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -103,7 +115,7 @@
|
|||||||
ElMessage.warning('请先登录')
|
ElMessage.warning('请先登录')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
await userStore.mqttClient?.subscribe(`zbjk_message_group/${lunTanRes.value.channelId}`)
|
await userStore.mqttClient?.subscribe(`zbjk_message_group/${lunTanRes.value!.channelId}`)
|
||||||
isChat.value = true
|
isChat.value = true
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="box-border w-320px border border-[#EEEEEE] rounded-8px border-solid bg-[#FFFFFF] px-23px py-25px">
|
<div class="box-border w-[320px] border border-[#EEEEEE] rounded-[8px] border-solid bg-[#FFFFFF] px-[23px] py-[25px]">
|
||||||
<div class="text-16px text-[#333333] font-normal">频道列表</div>
|
<div class="text-[16px] text-[#333333] font-normal">频道列表</div>
|
||||||
<div class="mt-30px">
|
<div class="mt-[30px]">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col v-for="(item, index) in channelIdList" :key="index" :span="8" class="mb-10px">
|
<el-col v-for="(item, index) in channelIdList" :key="index" :span="8" class="mb-[10px]">
|
||||||
<span
|
<span
|
||||||
class="cursor-pointer text-14px text-[#999999] font-normal"
|
class="cursor-pointer text-[14px] text-[#999999] font-normal"
|
||||||
:class="{ active: channelId === item.channelId }"
|
:class="{ active: channelId === item.channelId }"
|
||||||
@click="handleClick(item.channelId)"
|
@click="handleClick(item.channelId)"
|
||||||
>{{ item.channelTitle }}</span
|
>{{ item.channelTitle }}</span
|
||||||
@ -16,27 +16,32 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
// import { ref } from 'vue'
|
||||||
import { list } from '~/api/channel/index'
|
// import { list } from '~/api/channel/index'
|
||||||
|
|
||||||
const channelId = defineModel('modelValue', {
|
const channelId = defineModel('modelValue', {
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
/** 获取频道列表 */
|
|
||||||
const channelIdList = ref<any>([])
|
const channelIdList = defineModel<any[]>('channelIdList', {
|
||||||
const getChannelIdList = () => {
|
required: true,
|
||||||
list().then((res) => {
|
|
||||||
channelIdList.value = res.data
|
|
||||||
if (channelIdList.value.length > 0) {
|
|
||||||
channelId.value = channelIdList.value[0].channelId
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
/** 获取频道列表 */
|
||||||
getChannelIdList()
|
// const channelIdList = ref<any>([])
|
||||||
|
// const getChannelIdList = () => {
|
||||||
|
// list().then((res) => {
|
||||||
|
// channelIdList.value = res.data
|
||||||
|
// if (channelIdList.value.length > 0) {
|
||||||
|
// channelId.value = channelIdList.value[0].channelId
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// getChannelIdList()
|
||||||
|
|
||||||
const handleClick = (id: number) => {
|
const handleClick = (id: number) => {
|
||||||
console.log(id)
|
console.log(id)
|
||||||
channelId.value = id
|
channelId.value = id
|
||||||
|
navigateTo(`/channel/${id}/1`)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<!-- 用户信息 -->
|
<!-- 用户信息 -->
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<UserInfo></UserInfo>
|
<UserInfo></UserInfo>
|
||||||
<HotLlabel v-model="channelId" class="mt-18px"></HotLlabel>
|
<HotLlabel v-model="channelId" class="mt-18px" v-model:channelIdList="channelIdList"></HotLlabel>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -13,6 +13,10 @@
|
|||||||
const channelId = defineModel('modelValue', {
|
const channelId = defineModel('modelValue', {
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const channelIdList = defineModel<any>('channelIdList', {
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|||||||
@ -1,37 +1,39 @@
|
|||||||
<template>
|
<template>
|
||||||
<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 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
|
||||||
v-for="(item, index) in pageRes.list"
|
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
|
||||||
|
v-for="(item, index) in pageRes?.list"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="flex justify-between border-b-1px border-b-[#eee] border-b-solid pb-8px"
|
class="flex justify-between border-b-[1px] border-b-[#eee] border-b-solid pb-[8px]"
|
||||||
:class="{ 'border-b-0! pb-0px!': index === pageRes.list.length - 1 }"
|
:class="{ 'border-b-0! pb-[0px]!': index === pageRes!.list!.length - 1 }"
|
||||||
@click="handleClick(item.postsId)"
|
@click="handleClick(item.postsId)"
|
||||||
>
|
>
|
||||||
<div class="flex flex-1 items-center">
|
<div class="flex flex-1 items-center">
|
||||||
<div class="ellipsis max-w-70% text-15px text-[#2d3137] font-normal">{{ item.postsTitle }}</div>
|
<div class="ellipsis max-w-[70%] text-[15px] text-[#2d3137] font-normal">{{ item.postsTitle }}</div>
|
||||||
<span class="ml-10px flex-shrink-0 text-13px color-#96999f">{{ item.likeNum || 0 }}人赞过</span>
|
<span class="ml-[10px] flex-shrink-0 text-[13px] color-[#96999f]">{{ item.likeNum || 0 }}人赞过</span>
|
||||||
<span class="ml-10px flex-shrink-0 text-13px color-#96999f">{{ item.commentNum || 0 }}评论</span>
|
<span class="ml-[10px] flex-shrink-0 text-[13px] color-[#96999f]">{{ item.commentNum || 0 }}评论</span>
|
||||||
<span class="ml-10px flex-shrink-0 text-13px color-#96999f">{{ dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss') }}发布</span>
|
<span class="ml-[10px] flex-shrink-0 text-[13px] color-[#96999f]">{{ dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss') }}发布</span>
|
||||||
</div>
|
</div>
|
||||||
<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="handleDelete(item.postsId)">删除</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-pagination
|
<el-pagination
|
||||||
v-if="pageRes.list.length > 0"
|
v-if="pageRes?.list.length"
|
||||||
v-model:current-page="pageNo"
|
v-model:current-page="pageNo"
|
||||||
:page-size="10"
|
:page-size="10"
|
||||||
layout="prev, pager, next"
|
layout="prev, pager, next"
|
||||||
:total="pageRes.total"
|
:total="pageRes?.total"
|
||||||
@current-change="handleCurrentChange"
|
@current-change="handleCurrentChange"
|
||||||
/>
|
/>
|
||||||
<!-- 暂无数据 -->
|
<!-- 暂无数据 -->
|
||||||
<el-empty v-if="!pageRes.list.length" description="暂无数据"></el-empty>
|
<el-empty v-if="!pageRes?.list.length" description="暂无数据"></el-empty>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -43,10 +45,10 @@
|
|||||||
|
|
||||||
const emit = defineEmits(['updatePageNo'])
|
const emit = defineEmits(['updatePageNo'])
|
||||||
|
|
||||||
const pageRes = defineModel<TpageRes>('modelValue', {
|
const pageRes = defineModel<TpageRes | null>('modelValue', {
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
const lunTanRes = defineModel<ChannelRespVO>('lunTanRes', {
|
const lunTanRes = defineModel<ChannelRespVO | null>('lunTanRes', {
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
const pageNo = defineModel<number>('pageNo', {
|
const pageNo = defineModel<number>('pageNo', {
|
||||||
@ -73,7 +75,7 @@
|
|||||||
|
|
||||||
const handleClick = (channelId: number) => {
|
const handleClick = (channelId: number) => {
|
||||||
// 新开窗口
|
// 新开窗口
|
||||||
window.open(`/chat-detail?channelId=${channelId}`, '_blank')
|
navigateTo(`/chat-detail/${channelId}-1`)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -36,7 +36,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import useUserStore from '~/store/user'
|
import useUserStore from '~/stores/user'
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
// 判断是否登录
|
// 判断是否登录
|
||||||
@ -44,6 +44,6 @@
|
|||||||
ElMessage.warning('请先登录')
|
ElMessage.warning('请先登录')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
window.open('/channel/create', '_blank')
|
navigateTo('/channel/create')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,367 +0,0 @@
|
|||||||
<template>
|
|
||||||
<KlNavTab></KlNavTab>
|
|
||||||
<div class="mx-auto w-1440px">
|
|
||||||
<!-- 使用 el-form 重构表单区域 -->
|
|
||||||
<el-form ref="formRef" inline :model="formData" label-width="110px" class="custom-form mb-20px mt-20px border rounded p-20px!">
|
|
||||||
<el-form-item label="标题:" prop="postsTitle" :rules="{ required: true, message: '请输入标题', trigger: 'blur' }">
|
|
||||||
<el-input v-model="formData.postsTitle" placeholder="请输入标题" class="w-300px!" minlength="4" maxlength="40"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="分类:" class="mb-10px" prop="projectDicId" :rules="{ required: true, message: '请选择分类', trigger: ['blur', 'change'] }">
|
|
||||||
<el-select v-model="formData.projectDicId" placeholder="请选择分类" class="w-300px!">
|
|
||||||
<el-option v-for="item in projectTypeList" :key="item.id" :label="item.name" :value="item.id" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item label="标签:" class="mb-10px" prop="postsTags" :rules="{ required: true, message: '请输入标签', trigger: ['blur', 'change'] }">
|
|
||||||
<el-select
|
|
||||||
v-model="formData.postsTags"
|
|
||||||
:remote-method="remoteMethod"
|
|
||||||
:loading="loading"
|
|
||||||
filterable
|
|
||||||
remote
|
|
||||||
multiple
|
|
||||||
placeholder="请输入搜索标签"
|
|
||||||
class="w-300px!"
|
|
||||||
>
|
|
||||||
<el-option v-for="(item, index) in labelsList" :key="index" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="频道列表:" class="mb-10px" prop="channelId" :rules="{ required: true, message: '请选择频道', trigger: ['blur', 'change'] }">
|
|
||||||
<el-select v-model="formData.channelId" placeholder="请选择频道" class="w-300px!">
|
|
||||||
<el-option v-for="item in channelIdList" :key="item.channelId" :label="item.channelTitle" :value="item.channelId" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- <el-form-item label="上传封面:" prop="postsCover" :rules="{ required: true, message: '请上传封面', trigger: ['blur', 'change'] }">
|
|
||||||
<KlUploader v-model:file-list="formData.postsCover" :limit="1" :size="1" tips="上传图片支持jpg/gif/png格式"> </KlUploader>
|
|
||||||
</el-form-item> -->
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<Editor :id="tinymceId" v-model="myValue" :init="init" :disabled="disabled" :placeholder="placeholder" />
|
|
||||||
<!-- 按钮区域 -->
|
|
||||||
<div class="mt-20px flex justify-end">
|
|
||||||
<el-button :loading="post_loading" class="mr-10px" @click="previewContent">预览</el-button>
|
|
||||||
<el-button :loading="post_loading" type="primary" @click="saveContent">发表</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { keywords } from '~/api/upnew/index'
|
|
||||||
import { reactive, ref, onMounted } from 'vue'
|
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
|
||||||
const router = useRouter()
|
|
||||||
const route = useRoute()
|
|
||||||
import { create, list } from '~/api/channel/index'
|
|
||||||
import { parent } from '~/api/upnew/index'
|
|
||||||
import { upload } from '~/api/common/index' // 自定义上传方法
|
|
||||||
import Editor from '@tinymce/tinymce-vue'
|
|
||||||
import tinymce from 'tinymce/tinymce'
|
|
||||||
import 'tinymce/themes/silver'
|
|
||||||
import 'tinymce/themes/silver/theme'
|
|
||||||
import 'tinymce/models/dom'
|
|
||||||
import 'tinymce/icons/default'
|
|
||||||
import 'tinymce/icons/default/icons'
|
|
||||||
// 引入编辑器插件
|
|
||||||
import 'tinymce/plugins/code' //编辑源码
|
|
||||||
import 'tinymce/plugins/image' //插入编辑图片
|
|
||||||
import 'tinymce/plugins/media' //插入视频
|
|
||||||
import 'tinymce/plugins/link' //超链接
|
|
||||||
import 'tinymce/plugins/preview' //预览
|
|
||||||
// import 'tinymce/plugins/template' //模板
|
|
||||||
import 'tinymce/plugins/table' //表格
|
|
||||||
import 'tinymce/plugins/pagebreak' //分页
|
|
||||||
import 'tinymce/plugins/lists' //列
|
|
||||||
import 'tinymce/plugins/advlist' //列
|
|
||||||
import 'tinymce/plugins/quickbars' //快速工具条
|
|
||||||
import 'tinymce/plugins/wordcount' // 字数统计插件
|
|
||||||
// import '~/assets/tinymce/langs/zh-Hans.js' //下载后的语言包
|
|
||||||
// import 'tinymce/skins/content/default/content.css'
|
|
||||||
// 获取从其他地方传过来的参数
|
|
||||||
const channelId = route.query.channelId as string
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
value: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
placeholder: {
|
|
||||||
type: String,
|
|
||||||
default: '请输入帖子内容',
|
|
||||||
},
|
|
||||||
height: {
|
|
||||||
type: Number,
|
|
||||||
default: 500,
|
|
||||||
},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
plugins: {
|
|
||||||
type: [String, Array],
|
|
||||||
default: 'code image link preview table quickbars pagebreak lists advlist',
|
|
||||||
},
|
|
||||||
toolbar: {
|
|
||||||
type: [String, Array],
|
|
||||||
default:
|
|
||||||
'undo redo codesample bold italic underline strikethrough link alignleft aligncenter alignright alignjustify \
|
|
||||||
bullist numlist outdent indent removeformat forecolor backcolor |formatselect fontselect fontsizeselect | \
|
|
||||||
blocks fontfamily fontsize pagebreak lists image customvideoupload table preview | code selectall',
|
|
||||||
},
|
|
||||||
templates: {
|
|
||||||
type: Array,
|
|
||||||
default: () => [],
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
type: Object,
|
|
||||||
default: () => ({}),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
//用于接收外部传递进来的富文本
|
|
||||||
const myValue = ref(props.value)
|
|
||||||
const tinymceId = ref('vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + ''))
|
|
||||||
const init = reactive({
|
|
||||||
selector: '#' + tinymceId.value, //富文本编辑器的id,
|
|
||||||
language_url: '/tinymce/langs/zh_CN.js', // 语言包的路径,具体路径看自己的项目,文档后面附上中文js文件
|
|
||||||
language: 'zh-Hans', //语言
|
|
||||||
skin_url: '/tinymce/skins/ui/oxide', // skin路径,具体路径看自己的项目
|
|
||||||
content_css: '/tinymce/skins/content/default/content.css',
|
|
||||||
menubar: true, //顶部菜单栏显示
|
|
||||||
statusbar: true, // 底部的状态栏
|
|
||||||
plugins: props.plugins,
|
|
||||||
toolbar: props.toolbar,
|
|
||||||
toolbar_mode: 'sliding',
|
|
||||||
font_formats: 'Arial=arial,helvetica,sans-serif; 宋体=SimSun; 微软雅黑=Microsoft Yahei; Impact=impact,chicago;', //字体
|
|
||||||
paste_convert_word_fake_lists: false, // 插入word文档需要该属性
|
|
||||||
font_size_formats: '12px 14px 16px 18px 22px 24px 36px 72px', //文字大小
|
|
||||||
height: props.height, //编辑器高度
|
|
||||||
placeholder: props.placeholder,
|
|
||||||
branding: false, //是否禁用"Powered by TinyMCE"
|
|
||||||
promotion: false, //禁用升级按钮
|
|
||||||
image_dimensions: false, //去除宽高属性
|
|
||||||
paste_webkit_styles: 'all',
|
|
||||||
paste_merge_formats: true,
|
|
||||||
nonbreaking_force_tab: false,
|
|
||||||
paste_auto_cleanup_on_paste: false,
|
|
||||||
file_picker_types: 'file',
|
|
||||||
resize: true,
|
|
||||||
elementpath: true,
|
|
||||||
content_style: `img {max-width:100%;} body{background-color: #fff;}`, // 直接自定义可编辑区域的css样式
|
|
||||||
templates: props.templates,
|
|
||||||
quickbars_selection_toolbar: 'forecolor backcolor bold italic underline strikethrough link',
|
|
||||||
quickbars_image_toolbar: 'alignleft aligncenter alignright',
|
|
||||||
quickbars_insert_toolbar: false,
|
|
||||||
image_caption: true,
|
|
||||||
image_advtab: true,
|
|
||||||
convert_urls: false,
|
|
||||||
images_upload_url: import.meta.env.VITE_BASE_API,
|
|
||||||
images_upload_handler: function (blobInfo: any, progress: any) {
|
|
||||||
console.log(blobInfo, progress)
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const data = new FormData()
|
|
||||||
data.append('file', blobInfo.blob())
|
|
||||||
data.append('fieldName', blobInfo.filename())
|
|
||||||
upload('/prod-api/app-api/infra/file/upload', data)
|
|
||||||
.then((res) => {
|
|
||||||
resolve(res.data)
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
reject('Image upload failed')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// 添加自定义按钮
|
|
||||||
setup: function (editor: any) {
|
|
||||||
// 注册一个新的视频上传按钮
|
|
||||||
editor.ui.registry.addButton('customvideoupload', {
|
|
||||||
icon: 'embed', // 使用嵌入媒体图标
|
|
||||||
tooltip: '上传视频',
|
|
||||||
onAction: function () {
|
|
||||||
// 创建文件输入元素
|
|
||||||
const input = document.createElement('input')
|
|
||||||
input.setAttribute('type', 'file')
|
|
||||||
input.setAttribute('accept', 'video/*')
|
|
||||||
|
|
||||||
// 处理文件选择事件
|
|
||||||
input.onchange = function () {
|
|
||||||
if (input.files && input.files[0]) {
|
|
||||||
const file = input.files[0]
|
|
||||||
const data = new FormData()
|
|
||||||
data.append('file', file)
|
|
||||||
data.append('fieldName', file.name)
|
|
||||||
|
|
||||||
// 可以在这里添加上传进度显示
|
|
||||||
|
|
||||||
upload('/prod-api/app-api/infra/file/upload', data)
|
|
||||||
.then((res) => {
|
|
||||||
// 插入视频到编辑器
|
|
||||||
editor.insertContent(`
|
|
||||||
<video controls width="400">
|
|
||||||
<source src="${res.data}" type="video/${file.name.split('.').pop()}">
|
|
||||||
您的浏览器不支持视频标签
|
|
||||||
</video>
|
|
||||||
`)
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error('视频上传失败:', error)
|
|
||||||
// 可以添加错误提示
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 触发文件选择
|
|
||||||
input.click()
|
|
||||||
},
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
preview_styles: true,
|
|
||||||
...props.options,
|
|
||||||
})
|
|
||||||
|
|
||||||
// 表单数据
|
|
||||||
const formData = ref({
|
|
||||||
projectDicId: undefined,
|
|
||||||
postsTags: [],
|
|
||||||
postsCover: [] as any,
|
|
||||||
postsTitle: '',
|
|
||||||
channelId: channelId || undefined,
|
|
||||||
})
|
|
||||||
|
|
||||||
const formRef = ref()
|
|
||||||
const post_loading = ref(false)
|
|
||||||
const saveContent = () => {
|
|
||||||
formRef.value.validate().then(() => {
|
|
||||||
if (!myValue.value) {
|
|
||||||
ElMessage.error('请输入帖子内容')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
post_loading.value = true
|
|
||||||
create({
|
|
||||||
postsTitle: formData.value.postsTitle,
|
|
||||||
// postsCover: formData.value.postsCover[0].url,
|
|
||||||
postsTags: formData.value.postsTags.join(','),
|
|
||||||
postsContent: myValue.value,
|
|
||||||
projectDicId: formData.value.projectDicId,
|
|
||||||
channelId: formData.value.channelId,
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
console.log(res)
|
|
||||||
if (res.code === 0) {
|
|
||||||
ElMessage.success('发表成功')
|
|
||||||
router.push('/communication/channel')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log(err)
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
post_loading.value = false
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const previewContent = () => {
|
|
||||||
// 获取编辑器实例
|
|
||||||
const editor = tinymce.get(tinymceId.value)
|
|
||||||
// 调用编辑器的预览命令
|
|
||||||
if (editor) {
|
|
||||||
editor.execCommand('mcePreview')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//在onMounted中初始化编辑器
|
|
||||||
onMounted(() => {
|
|
||||||
tinymce.init({})
|
|
||||||
})
|
|
||||||
|
|
||||||
/** 获取频道列表 */
|
|
||||||
const channelIdList = ref<any>([])
|
|
||||||
const getChannelIdList = () => {
|
|
||||||
list().then((res) => {
|
|
||||||
channelIdList.value = res.data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
getChannelIdList()
|
|
||||||
|
|
||||||
const projectTypeList = ref<any>([])
|
|
||||||
/** 获取分类下拉框 */
|
|
||||||
const getParent = () => {
|
|
||||||
parent({
|
|
||||||
type: 1,
|
|
||||||
parentId: 0,
|
|
||||||
}).then((res) => {
|
|
||||||
projectTypeList.value = res.data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
getParent()
|
|
||||||
|
|
||||||
const loading = ref(false)
|
|
||||||
/** 获取标签 */
|
|
||||||
const labelsList = ref<any>([])
|
|
||||||
const remoteMethod = (query: string) => {
|
|
||||||
if (query) {
|
|
||||||
loading.value = true
|
|
||||||
keywords({
|
|
||||||
type: 1,
|
|
||||||
keywords: query,
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
labelsList.value = res.data
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
loading.value = false
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
labelsList.value = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.custom-form {
|
|
||||||
border: 2px solid #eeeeee;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.upload-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cover-uploader {
|
|
||||||
:deep(.el-upload) {
|
|
||||||
width: fit-content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.image-error {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
color: #909399;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image-actions {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.el-form-item__label) {
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.el-button--primary.is-link) {
|
|
||||||
padding: 0;
|
|
||||||
height: auto;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-gray-500 {
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-12px {
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
352
pages/channel/create/index.vue
Normal file
352
pages/channel/create/index.vue
Normal file
@ -0,0 +1,352 @@
|
|||||||
|
<template>
|
||||||
|
<KlNavTab></KlNavTab>
|
||||||
|
<div class="mx-auto w-[1440px]">
|
||||||
|
<!-- 使用 el-form 重构表单区域 -->
|
||||||
|
<el-form ref="formRef" inline :model="formData" label-width="110px" class="custom-form mb-[20px] mt-[20px] border rounded p-[20px]!">
|
||||||
|
<el-form-item label="标题:" prop="postsTitle" :rules="{ required: true, message: '请输入标题', trigger: 'blur' }">
|
||||||
|
<el-input v-model="formData.postsTitle" placeholder="请输入标题" class="w-[300px]!" minlength="4" maxlength="40"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="分类:" class="mb-[10px]" prop="projectDicId" :rules="{ required: true, message: '请选择分类', trigger: ['blur', 'change'] }">
|
||||||
|
<el-select v-model="formData.projectDicId" placeholder="请选择分类" class="w-[300px]!">
|
||||||
|
<el-option v-for="item in projectTypeList" :key="item.id" :label="item.name" :value="item.id" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="标签:" class="mb-[10px]" prop="postsTags" :rules="{ required: true, message: '请输入标签', trigger: ['blur', 'change'] }">
|
||||||
|
<el-select
|
||||||
|
v-model="formData.postsTags"
|
||||||
|
:remote-method="remoteMethod"
|
||||||
|
:loading="loading"
|
||||||
|
filterable
|
||||||
|
remote
|
||||||
|
multiple
|
||||||
|
placeholder="请输入搜索标签"
|
||||||
|
class="w-[300px]!"
|
||||||
|
>
|
||||||
|
<el-option v-for="(item, index) in labelsList" :key="index" :label="item" :value="item" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="频道列表:" class="mb-[10px]" prop="channelId" :rules="{ required: true, message: '请选择频道', trigger: ['blur', 'change'] }">
|
||||||
|
<el-select v-model="formData.channelId" placeholder="请选择频道" class="w-[300px]!">
|
||||||
|
<el-option v-for="item in channelIdList" :key="item.channelId" :label="item.channelTitle" :value="item.channelId" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- <el-form-item label="上传封面:" prop="postsCover" :rules="{ required: true, message: '请上传封面', trigger: ['blur', 'change'] }">
|
||||||
|
<KlUploader v-model:file-list="formData.postsCover" :limit="1" :size="1" tips="上传图片支持jpg/gif/png格式"> </KlUploader>
|
||||||
|
</el-form-item> -->
|
||||||
|
</el-form>
|
||||||
|
<div style="border: 1px solid #eeeeee; margin-top: 10px" class="rounded">
|
||||||
|
<WeToolbar style="border-bottom: 1px solid #eeeeee" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
|
||||||
|
|
||||||
|
<WeEditor
|
||||||
|
style="min-height: 300px; overflow-y: hidden"
|
||||||
|
v-model="valueHtml"
|
||||||
|
:defaultConfig="editorConfig"
|
||||||
|
:mode="mode"
|
||||||
|
@onCreated="handleCreated"
|
||||||
|
@onChange="handleChange"
|
||||||
|
@onDestroyed="handleDestroyed"
|
||||||
|
@onFocus="handleFocus"
|
||||||
|
@onBlur="handleBlur"
|
||||||
|
@customAlert="customAlert"
|
||||||
|
@customPaste="customPaste"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<!-- 按钮区域 -->
|
||||||
|
<div class="mt-[20px] flex justify-end">
|
||||||
|
<!-- <el-button :loading="post_loading" class="mr-10px" @click="previewContent">预览</el-button> -->
|
||||||
|
<el-button :loading="post_loading" type="primary" @click="saveContent">发表</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { keywords } from '@/api/upnew/index'
|
||||||
|
import { reactive, ref, onMounted } from 'vue'
|
||||||
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
import { create, list } from '@/api/channel/index'
|
||||||
|
import { parent } from '@/api/upnew/index'
|
||||||
|
import { upload } from '@/api/common/index' // 自定义上传方法
|
||||||
|
import '@wangeditor/editor/dist/css/style.css' // 引入 css
|
||||||
|
// import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
|
||||||
|
import { onBeforeUnmount, shallowRef } from 'vue'
|
||||||
|
|
||||||
|
import useUserStore from '~/stores/user'
|
||||||
|
const userStore = useUserStore()
|
||||||
|
// 获取从其他地方传过来的参数
|
||||||
|
const channelId = route.query.channelId as string
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: '请输入帖子内容',
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
type: Number,
|
||||||
|
default: 500,
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
type: [String, Array],
|
||||||
|
default: 'code image link preview table quickbars pagebreak lists advlist',
|
||||||
|
},
|
||||||
|
toolbar: {
|
||||||
|
type: [String, Array],
|
||||||
|
default:
|
||||||
|
'undo redo codesample bold italic underline strikethrough link alignleft aligncenter alignright alignjustify \
|
||||||
|
bullist numlist outdent indent removeformat forecolor backcolor |formatselect fontselect fontsizeselect | \
|
||||||
|
blocks fontfamily fontsize pagebreak lists image customvideoupload table preview | code selectall',
|
||||||
|
},
|
||||||
|
templates: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const mode = 'default'
|
||||||
|
|
||||||
|
const isClient = ref(false)
|
||||||
|
if (import.meta.client) {
|
||||||
|
isClient.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑器实例,必须用 shallowRef
|
||||||
|
const editorRef = shallowRef()
|
||||||
|
|
||||||
|
// 内容 HTML
|
||||||
|
const valueHtml = ref('<p></p>')
|
||||||
|
|
||||||
|
// 模拟 ajax 异步获取内容
|
||||||
|
onMounted(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
valueHtml.value = '<p></p>'
|
||||||
|
}, 1500)
|
||||||
|
})
|
||||||
|
|
||||||
|
const toolbarConfig = {}
|
||||||
|
const editorConfig = {
|
||||||
|
placeholder: '请输入内容...',
|
||||||
|
// 上传图片的配置
|
||||||
|
MENU_CONF: {
|
||||||
|
uploadImage: {
|
||||||
|
server: 'https://tuxixi.net/prod-api/app-api/infra/file/upload',
|
||||||
|
fieldName: 'file', //这个是参数名字
|
||||||
|
headers: {
|
||||||
|
//配置token 接口需要就配 不需要就不用
|
||||||
|
Authorization: `Bearer ${userStore.token}`,
|
||||||
|
},
|
||||||
|
customInsert(res: any, insertFn: any) {
|
||||||
|
// 这个是获取接口返回的数据
|
||||||
|
insertFn(res.data) // 从 res 中找到 url(也就是接口返回的图片地址),然后插入图片
|
||||||
|
},
|
||||||
|
},
|
||||||
|
uploadVideo: {
|
||||||
|
server: 'https://tuxixi.net/prod-api/app-api/infra/file/upload',
|
||||||
|
fieldName: 'file', //这个是参数名字
|
||||||
|
maxFileSize: 1200 * 1024 * 1024, // 1200M
|
||||||
|
headers: {
|
||||||
|
//配置token 接口需要就配 不需要就不用
|
||||||
|
Authorization: `Bearer ${userStore.token}`,
|
||||||
|
},
|
||||||
|
customInsert(res: any, insertFn: any) {
|
||||||
|
// 这个是获取接口返回的数据
|
||||||
|
insertFn(res.data) // 从 res 中找到 url(也就是接口返回的图片地址),然后插入图片
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const formData = ref({
|
||||||
|
projectDicId: undefined,
|
||||||
|
postsTags: [],
|
||||||
|
postsCover: [] as any,
|
||||||
|
postsTitle: '',
|
||||||
|
channelId: channelId || undefined,
|
||||||
|
})
|
||||||
|
|
||||||
|
const formRef = ref()
|
||||||
|
const post_loading = ref(false)
|
||||||
|
const saveContent = () => {
|
||||||
|
formRef.value.validate().then(() => {
|
||||||
|
if (!valueHtml.value) {
|
||||||
|
ElMessage.error('请输入帖子内容')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
post_loading.value = true
|
||||||
|
create({
|
||||||
|
postsTitle: formData.value.postsTitle,
|
||||||
|
// postsCover: formData.value.postsCover[0].url,
|
||||||
|
postsTags: formData.value.postsTags.join(','),
|
||||||
|
postsContent: valueHtml.value,
|
||||||
|
projectDicId: formData.value.projectDicId,
|
||||||
|
channelId: formData.value.channelId,
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
console.log(res)
|
||||||
|
if (res.code === 0) {
|
||||||
|
ElMessage.success('发表成功')
|
||||||
|
router.back()
|
||||||
|
// router.push('/communication/channel')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err)
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
post_loading.value = false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 组件销毁时,也及时销毁编辑器
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
const editor = editorRef.value
|
||||||
|
if (editor == null) return
|
||||||
|
editor.destroy()
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleCreated = (editor: any) => {
|
||||||
|
editorRef.value = editor // 记录 editor 实例,重要!
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChange = (editor: any) => {
|
||||||
|
console.log('change:', editor.getHtml())
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDestroyed = (editor: any) => {
|
||||||
|
console.log('destroyed', editor)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleFocus = (editor: any) => {
|
||||||
|
console.log('focus', editor)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleBlur = (editor: any) => {
|
||||||
|
console.log('blur', editor)
|
||||||
|
}
|
||||||
|
const customAlert = (info: any, type: any) => {
|
||||||
|
alert(`【自定义提示】${type} - ${info}`)
|
||||||
|
}
|
||||||
|
const customPaste = (editor: any, event: any, callback: any) => {
|
||||||
|
console.log('ClipboardEvent 粘贴事件对象', event)
|
||||||
|
// const html = event.clipboardData.getData('text/html') // 获取粘贴的 html
|
||||||
|
const text = event.clipboardData.getData('text/plain') // 获取粘贴的纯文本
|
||||||
|
// const rtf = event.clipboardData.getData('text/rtf') // 获取 rtf 数据(如从 word wsp 复制粘贴)
|
||||||
|
|
||||||
|
// 自定义插入内容
|
||||||
|
editor.insertText(text)
|
||||||
|
|
||||||
|
// 返回 false ,阻止默认粘贴行为
|
||||||
|
event.preventDefault()
|
||||||
|
callback(false) // 返回值(注意,vue 事件的返回值,不能用 return)
|
||||||
|
|
||||||
|
// 返回 true ,继续默认的粘贴行为
|
||||||
|
// callback(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取频道列表 */
|
||||||
|
const channelIdList = ref<any>([])
|
||||||
|
const getChannelIdList = () => {
|
||||||
|
list().then((res) => {
|
||||||
|
channelIdList.value = res.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
getChannelIdList()
|
||||||
|
|
||||||
|
const projectTypeList = ref<any>([])
|
||||||
|
/** 获取分类下拉框 */
|
||||||
|
const getParent = () => {
|
||||||
|
parent({
|
||||||
|
type: 1,
|
||||||
|
parentId: 0,
|
||||||
|
}).then((res) => {
|
||||||
|
projectTypeList.value = res.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
getParent()
|
||||||
|
|
||||||
|
const loading = ref(false)
|
||||||
|
/** 获取标签 */
|
||||||
|
const labelsList = ref<any>([])
|
||||||
|
const remoteMethod = (query: string) => {
|
||||||
|
if (query) {
|
||||||
|
loading.value = true
|
||||||
|
keywords({
|
||||||
|
type: 1,
|
||||||
|
keywords: query,
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
labelsList.value = res.data
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
labelsList.value = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.custom-form {
|
||||||
|
border: 2px solid #eeeeee;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cover-uploader {
|
||||||
|
:deep(.el-upload) {
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-error {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #909399;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-form-item__label) {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-button--primary.is-link) {
|
||||||
|
padding: 0;
|
||||||
|
height: auto;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-gray-500 {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-12px {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- 导航 -->
|
<!-- 导航 -->
|
||||||
<KlNavTab active="交流频道" />
|
<KlNavTab active="交流频道" />
|
||||||
<div class="ma-auto mt-30px w-1440px flex">
|
<div class="ma-auto mt-[30px] w-[1440px] flex">
|
||||||
<LeftContent v-model="pageReq.channelId"></LeftContent>
|
<LeftContent v-model="pageReq.channelId" v-model:channelIdList="channelIdList"></LeftContent>
|
||||||
<RightContent v-model="pageRes" v-model:lun-tan-res="lunTanRes" v-model:page-no="pageReq.pageNo" @update-page-no="handleUpdatePageNo"></RightContent>
|
<!-- <RightContent v-model="pageRes" v-model:lun-tan-res="lunTanRes" v-model:page-no="pageReq.pageNo" @update-page-no="handleUpdatePageNo"></RightContent> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -11,7 +11,7 @@
|
|||||||
import KlNavTab from '~/components/kl-nav-tab/index.vue'
|
import KlNavTab from '~/components/kl-nav-tab/index.vue'
|
||||||
import LeftContent from './components/LeftContent.vue'
|
import LeftContent from './components/LeftContent.vue'
|
||||||
import RightContent from './components/RightContent.vue'
|
import RightContent from './components/RightContent.vue'
|
||||||
import { page, getChannelLunTanDetail } from '~/api/channel/index'
|
import { page, getChannelLunTanDetail, list } from '~/api/channel/index'
|
||||||
import { reactive, watch, ref } from 'vue'
|
import { reactive, watch, ref } from 'vue'
|
||||||
import type { TpageRes, ChannelRespVO } from '~/api/channel/types'
|
import type { TpageRes, ChannelRespVO } from '~/api/channel/types'
|
||||||
|
|
||||||
@ -24,38 +24,60 @@
|
|||||||
list: [],
|
list: [],
|
||||||
total: 0,
|
total: 0,
|
||||||
})
|
})
|
||||||
// 获得频道帖子分页
|
|
||||||
const getPage = () => {
|
|
||||||
page(pageReq).then((res) => {
|
|
||||||
pageRes.list = res.data.list
|
|
||||||
pageRes.total = res.data.total
|
|
||||||
})
|
|
||||||
}
|
|
||||||
getPage()
|
|
||||||
|
|
||||||
const handleUpdatePageNo = (pageNo: number) => {
|
// 获取频道列表
|
||||||
pageReq.pageNo = pageNo
|
const { data: channelIdList } = await useAsyncData(`prod-api/app-api/business/channel/list-${Date.now()}`, async () => {
|
||||||
getPage()
|
const res = await list()
|
||||||
}
|
return res.data as any[]
|
||||||
|
})
|
||||||
|
|
||||||
|
// console.log(channelIdList)
|
||||||
|
|
||||||
|
// 获取第一个论坛详情
|
||||||
|
// if (!channelIdList.value?.length) return
|
||||||
|
// const { data: lunTanRes, execute } = await useAsyncData(`prod-api/app-api/business/channel/detail-${Date.now()}`, async () => {
|
||||||
|
// const res = await getChannelLunTanDetail({
|
||||||
|
// id: channelIdList.value?.[0].channelId,
|
||||||
|
// })
|
||||||
|
// return res.data as ChannelRespVO
|
||||||
|
// })
|
||||||
|
|
||||||
|
// const {data:pageRes, refresh:getPage} = await useAsyncData(`prod-api/app-api/business/posts/page-${Date.now()}`, async () => {
|
||||||
|
// const res = await page(pageReq)
|
||||||
|
// return res.data as TpageRes
|
||||||
|
// })
|
||||||
|
// 获得频道帖子分页
|
||||||
|
// const getPage = () => {
|
||||||
|
// page(pageReq).then((res) => {
|
||||||
|
// pageRes.list = res.data.list
|
||||||
|
// pageRes.total = res.data.total
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// getPage()
|
||||||
|
|
||||||
|
// const handleUpdatePageNo = (pageNo: number) => {
|
||||||
|
// pageReq.pageNo = pageNo
|
||||||
|
// getPage()
|
||||||
|
// }
|
||||||
|
|
||||||
// 获取论坛详情
|
// 获取论坛详情
|
||||||
const lunTanRes = ref({} as ChannelRespVO)
|
// const lunTanRes = ref({} as ChannelRespVO)
|
||||||
const getLunTanDetaiil = (val: string) => {
|
// const getLunTanDetaiil = (val: string) => {
|
||||||
getChannelLunTanDetail({
|
// getChannelLunTanDetail({
|
||||||
id: val,
|
// id: val,
|
||||||
}).then((res) => {
|
// }).then((res) => {
|
||||||
lunTanRes.value = res.data
|
// lunTanRes.value = res.data
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => pageReq.channelId,
|
() => channelIdList.value,
|
||||||
(val) => {
|
(val) => {
|
||||||
if (val) {
|
if (val) {
|
||||||
getPage()
|
navigateTo(`/channel/${val[0].channelId}/1`)
|
||||||
getLunTanDetaiil(val)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
)
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -1,70 +1,70 @@
|
|||||||
<template>
|
<template>
|
||||||
<KlNavTab />
|
<KlNavTab />
|
||||||
<div class="ml-auto mr-auto mt-20px w1440 flex">
|
<div class="ml-auto mr-auto mt-[20px] w-[1440px] flex">
|
||||||
<div class="left box-border w-1019px border border-[#EEEEEE] rounded-12px border-solid bg-[#FFFFFF] px-42px py-30px">
|
<div class="left box-border w-[100%] border border-[#EEEEEE] rounded-[12px] border-solid bg-[#FFFFFF] px-[42px] py-[30px]">
|
||||||
<div class="title text-24px text-[#333333] font-bold">{{ channelDetail?.postsTitle }}</div>
|
<div class="title text-[20px] text-[#333333] font-bold">{{ channelDetail?.postsTitle }}</div>
|
||||||
<div class="mt-20px flex items-center justify-between border-b-1px border-b-[#eee] border-b-solid pb-14px">
|
<div class="mt-[20px] flex items-center justify-between border-b-[1px] border-b-[#eee] border-b-solid pb-[14px]">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<img :src="channelDetail?.creatorAvatar" alt="" srcset="" class="h-50px w-49px rounded-full" />
|
<img :src="channelDetail?.creatorAvatar" alt="" srcset="" class="h-[50px] w-[49px] rounded-full" />
|
||||||
<div class="ml-10px">
|
<div class="ml-[10px]">
|
||||||
<div class="text-16px text-[#333333] font-normal">{{ channelDetail?.creatorName }}</div>
|
<div class="text-[16px] text-[#333333] font-normal">{{ channelDetail?.creatorName }}</div>
|
||||||
<div class="text-12px text-[#999999] font-normal">发表时间:{{ dayjs(channelDetail?.createTime).format('YYYY-MM-DD HH:mm:ss') }}</div>
|
<div class="text-[12px] text-[#999999] font-normal">发表时间:{{ dayjs(channelDetail?.createTime).format('YYYY-MM-DD HH:mm:ss') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</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-[17px]" />
|
||||||
<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-[23px]" />
|
||||||
<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-[17px]" />
|
||||||
<span class="text-[#666666]">{{ channelDetail?.browseNum || 0 }}人看过</span>
|
<span class="text-[#666666]">{{ channelDetail?.browseNum || 0 }}人看过</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<img :src="channelDetail?.postsCover" alt="" srcset="" class="h-396px w-auto" />
|
<img :src="channelDetail?.postsCover" alt="" srcset="" class="h-[396px] w-auto" />
|
||||||
<div class="mt-20px text-14px text-[#333333] font-normal" v-html="channelDetail?.postsContent"></div>
|
<div class="mt-[20px] text-[14px] text-[#333333] font-normal" v-html="channelDetail?.postsContent"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-30px">
|
<div class="mt-[30px]">
|
||||||
<div class="h-48px w-938px rounded-1px bg-[#F8F8F8] pl-10px text-16px text-[#333333] font-normal line-height-50px"
|
<div class="h-[48px] w-[100%] rounded-[1px] bg-[#F8F8F8] pl-[10px] text-[16px] text-[#333333] font-normal line-height-[50px]"
|
||||||
>共有{{ commentList.total || 0 }}条评论</div
|
>共有{{ commentList?.total || 0 }}条评论</div
|
||||||
>
|
>
|
||||||
<div v-for="item in commentList.list" :key="item.commentId" class="mt-10px border-b-1px border-b-[#eee] border-b-solid pb-14px">
|
<div v-for="item in commentList?.list" :key="item.commentId" class="mt-[10px] border-b-[1px] border-b-[#eee] border-b-solid pb-[14px]">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<img :src="item.creatorAvatar" alt="" srcset="" class="relative top-12px h-50px w-49px rounded-full" />
|
<img :src="item.creatorAvatar" alt="" srcset="" class="relative top-[12px] h-[50px] w-[49px] rounded-full" />
|
||||||
<div class="ml-10px">
|
<div class="ml-[10px]">
|
||||||
<span>{{ item.creatorName }}</span>
|
<span>{{ item.creatorName }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-12px text-[#999999] font-normal">发表时间:{{ dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss') }}</div>
|
<div class="text-[12px] text-[#999999] font-normal">发表时间:{{ dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss') }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-60px mt--10px box-border rd-4px bg-[#F8F8F8] pa-6px px-8px text-14px text-[#999999] font-normal">{{ item.content }}</div>
|
<div class="ml-[60px] mt-[-10px] box-border rd-[4px] bg-[#F8F8F8] pa-[6px] px-[8px] text-[14px] text-[#999999] font-normal">{{ item.content }}</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 添加element-plus分页 -->
|
<!-- 添加element-plus分页 -->
|
||||||
<el-pagination
|
<el-pagination
|
||||||
v-model:current-page="query.pageNo"
|
v-model:current-page="query.pageNo"
|
||||||
:page-size="query.pageSize"
|
:page-size="query.pageSize"
|
||||||
layout="prev, pager, next"
|
layout="prev, pager, next"
|
||||||
:total="commentList.total"
|
:total="commentList?.total"
|
||||||
class="mt-10px"
|
class="mt-[10px]"
|
||||||
@current-change="handleCurrentChange"
|
@current-change="handleCurrentChange"
|
||||||
/>
|
/>
|
||||||
<el-input v-model="commentContent" type="textarea" :rows="6" placeholder="请输入内容" class="mt-20px w-100%"></el-input>
|
<el-input v-model="commentContent" type="textarea" :rows="6" placeholder="请输入内容" class="mt-[20px] w-[100%]"></el-input>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<el-button type="primary" class="mt-10px h-40px w-101px rounded-4px text-16px text-[#FFFFFF] font-bold" @click="handleCreateComment"
|
<el-button type="primary" class="mt-[10px] h-[40px] w-[101px] rounded-[4px] text-[16px] text-[#FFFFFF] font-bold" @click="handleCreateComment"
|
||||||
>发表评论</el-button
|
>发表评论</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="right ml-23px w-100%">
|
<!-- <div class="right ml-23px w-100%">
|
||||||
<div class="mt-20px w-398px border border-[#EEEEEE] border-rd-[10px_10px_0px_0px] border-solid bg-[#FFFFFF]">
|
<div class="mt-20px w-398px border border-[#EEEEEE] border-rd-[10px_10px_0px_0px] border-solid bg-[#FFFFFF]">
|
||||||
<img src="~/assets/images/sign.png" alt="" srcset="" class="h-206px w-100%" />
|
<img src="~/assets/images/sign.png" alt="" srcset="" class="h-206px w-100%" />
|
||||||
<div class="box-border border border-[#EEEEEE] border-rd-[10px_10px_0px_0px] border-solid border-t-none bg-[#FFFFFF] pa-18px">
|
<div class="box-border border border-[#EEEEEE] border-rd-[10px_10px_0px_0px] border-solid border-t-none bg-[#FFFFFF] pa-18px">
|
||||||
@ -89,7 +89,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -101,50 +101,69 @@
|
|||||||
import { getChannelDetail, postscommentpage, createPostsComment } from '~/api/channel'
|
import { getChannelDetail, postscommentpage, createPostsComment } from '~/api/channel'
|
||||||
import type { TGetChannelPostsRes, PageResultPostsCommentRespVO } from '~/api/channel/types'
|
import type { TGetChannelPostsRes, PageResultPostsCommentRespVO } from '~/api/channel/types'
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const channelId = route.query.channelId as string
|
const channelId = computed(() => route.params.channelId as string)
|
||||||
|
const pageNo = computed(() => Number(route.params.pageNo))
|
||||||
|
|
||||||
const channelDetail = ref<TGetChannelPostsRes>()
|
console.log(channelId.value, pageNo.value)
|
||||||
const commentList = reactive<PageResultPostsCommentRespVO>({
|
|
||||||
list: [],
|
// const channelDetail = ref<TGetChannelPostsRes>()
|
||||||
total: 0,
|
// const commentList = reactive<PageResultPostsCommentRespVO>({
|
||||||
|
// list: [],
|
||||||
|
// total: 0,
|
||||||
|
// })
|
||||||
|
|
||||||
|
const { data: channelDetail } = await useAsyncData(`prod-api/app-api/business/posts/detail-${Date.now()}`, async () => {
|
||||||
|
const res = await getChannelDetail({
|
||||||
|
id: channelId.value,
|
||||||
})
|
})
|
||||||
const getChannel = () => {
|
return res.data as TGetChannelPostsRes
|
||||||
getChannelDetail({
|
|
||||||
id: channelId,
|
|
||||||
}).then((res) => {
|
|
||||||
if (res.code === 0) {
|
|
||||||
channelDetail.value = res.data
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
// const getChannel = () => {
|
||||||
|
// getChannelDetail({
|
||||||
|
// id: channelId,
|
||||||
|
// }).then((res) => {
|
||||||
|
// if (res.code === 0) {
|
||||||
|
// channelDetail.value = res.data
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
const query = reactive({
|
const query = reactive({
|
||||||
pageNo: 1,
|
pageNo: pageNo.value,
|
||||||
pageSize: 4,
|
pageSize: 4,
|
||||||
})
|
})
|
||||||
const getComment = () => {
|
|
||||||
postscommentpage({
|
const { data: commentList, refresh } = await useAsyncData(`prod-api/app-api/business/posts/comment/page-${Date.now()}`, async () => {
|
||||||
postsId: channelId,
|
const res = await postscommentpage({
|
||||||
pageNo: query.pageNo,
|
postsId: channelId.value,
|
||||||
pageSize: query.pageSize,
|
pageNo: pageNo.value,
|
||||||
}).then((res) => {
|
pageSize: 4,
|
||||||
if (res.code === 0) {
|
|
||||||
commentList.list = res.data.list
|
|
||||||
commentList.total = res.data.total
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
return res.data as PageResultPostsCommentRespVO
|
||||||
watch(
|
})
|
||||||
() => channelId,
|
// const getComment = () => {
|
||||||
(val) => {
|
// postscommentpage({
|
||||||
if (val) {
|
// postsId: channelId,
|
||||||
getChannel()
|
// pageNo: query.pageNo,
|
||||||
getComment()
|
// pageSize: query.pageSize,
|
||||||
}
|
// }).then((res) => {
|
||||||
},
|
// if (res.code === 0) {
|
||||||
{
|
// commentList.list = res.data.list
|
||||||
immediate: true,
|
// commentList.total = res.data.total
|
||||||
}
|
// }
|
||||||
)
|
// })
|
||||||
|
// }
|
||||||
|
// watch(
|
||||||
|
// () => channelId,
|
||||||
|
// (val) => {
|
||||||
|
// if (val) {
|
||||||
|
// getChannel()
|
||||||
|
// getComment()
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// immediate: true,
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
|
||||||
const commentContent = ref('')
|
const commentContent = ref('')
|
||||||
const handleCreateComment = () => {
|
const handleCreateComment = () => {
|
||||||
@ -153,17 +172,18 @@
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
createPostsComment({
|
createPostsComment({
|
||||||
postsId: channelId,
|
postsId: channelId.value,
|
||||||
content: commentContent.value,
|
content: commentContent.value,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
getComment()
|
refresh()
|
||||||
commentContent.value = ''
|
commentContent.value = ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const handleCurrentChange = (pageNo: number) => {
|
const handleCurrentChange = (pageNo: number) => {
|
||||||
query.pageNo = pageNo
|
// query.pageNo = pageNo
|
||||||
getComment()
|
// getComment()
|
||||||
|
navigateTo(`/chat-detail/${channelId.value}-${pageNo}`)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -106,7 +106,7 @@
|
|||||||
import type { msgType, PageResultMessageRespVO, MemberUserRespDTO } from '~/api/channel/types'
|
import type { msgType, PageResultMessageRespVO, MemberUserRespDTO } from '~/api/channel/types'
|
||||||
import { ref, onMounted, nextTick, watch, onUnmounted } from 'vue'
|
import { ref, onMounted, nextTick, watch, onUnmounted } from 'vue'
|
||||||
// import dayjs from 'dayjs'
|
// import dayjs from 'dayjs'
|
||||||
import useUserStore from '~/store/user'
|
import useUserStore from '~/stores/user'
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|||||||
372
pages/down-drawe-detail/[id].vue
Normal file
372
pages/down-drawe-detail/[id].vue
Normal file
@ -0,0 +1,372 @@
|
|||||||
|
<template>
|
||||||
|
<SeoHead :title="detail?.title" :description="detail?.description" :keywords="detail?.labels?.toString()" />
|
||||||
|
<KlNavTab />
|
||||||
|
<div class="ml-auto mr-auto mt-[20px] w-[1440px]">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div
|
||||||
|
class="box-border h-[60px] w-[1019px] flex items-center justify-between border border-[#EEEEEE] rounded-[12px] border-solid bg-[#FFFFFF] px-[27px] py-[24px]"
|
||||||
|
>
|
||||||
|
<div class="text-[20px] text-[#333333] font-normal"> {{ detail?.title }}</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<img :src="detail?.ownedUserIdInfo?.avatar" alt="" srcset="" class="h-[30px] w-[30px] rd-[50%]" />
|
||||||
|
<span class="ml-[12px] color-[#999999]">by {{ detail?.ownedUserIdInfo?.nickName }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ml-[23px] flex flex-1 text-[18px] text-[#FFFFFF] font-normal">
|
||||||
|
<div class="h-[60px] w-[160px] flex cursor-pointer items-center justify-center rounded-[8px] bg-[#1A65FF]" @click="handleDownload">
|
||||||
|
<img src="~/assets/images/download.png" alt="" srcset="" class="mr-[4px] h-[22px] w-[27px]" />
|
||||||
|
{{ detail?.points === 0 ? '免费下载' : '立即下载' }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="!detail?.favoriteId"
|
||||||
|
class="ml-[11px] h-[60px] flex flex-1 cursor-pointer items-center justify-center rounded-[8px] bg-[#E7B03B]"
|
||||||
|
@click="handleCollect"
|
||||||
|
><img src="~/assets/images/collect.png" alt="" srcset="" class="mr-[4px] h-[24px] w-[24px]" /> 收藏</div
|
||||||
|
>
|
||||||
|
<div v-else class="ml-[11px] h-[60px] flex flex-1 cursor-pointer items-center justify-center rounded-[8px] bg-[#E7B03B]" @click="handleCollect"
|
||||||
|
><img src="~/assets/images/wjx2.png" alt="" srcset="" class="mr-[4px] h-[18px] w-[18px]" /> 已收藏</div
|
||||||
|
>
|
||||||
|
|
||||||
|
<div class="ml-[11px] h-[60px] flex flex-1 cursor-pointer items-center justify-center rounded-[8px] bg-[#F56C6C]" @click="handleReport"
|
||||||
|
><el-icon class="mr-[4px] mt-[4px]"><Warning /></el-icon> 举报</div
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- -->
|
||||||
|
<div class="ma-auto mt-[21px] flex">
|
||||||
|
<div class="w-[1019px]">
|
||||||
|
<div>
|
||||||
|
<ThumBnail :data="detail?.coverImages" :type="detail?.type"></ThumBnail>
|
||||||
|
</div>
|
||||||
|
<div class="mb-[20px] mt-[34px] flex items-center text-[16px] text-[#333333] font-normal">
|
||||||
|
<div class="h-[24px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div><span class="ml-[10px]">{{ detail?.title }}描述</span></div
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="box-border min-h-[90px] w-[1019px] border border-[#EEEEEE] rounded-[6px] border-solid bg-[#FFFFFF] pa-[24px] text-[14px] text-[#333333] font-normal"
|
||||||
|
>
|
||||||
|
{{ detail?.description }}
|
||||||
|
</div>
|
||||||
|
<div id="section1" class="mb-[20px] mt-[34px] flex items-center text-[16px] text-[#333333] font-normal">
|
||||||
|
<div class="h-[24px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div><span class="ml-[10px]">{{ detail?.title }}附件</span></div
|
||||||
|
>
|
||||||
|
<div 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]">
|
||||||
|
{{ detail?.type === 1 ? '图纸' : detail?.type === 2 ? '文本' : '模型' }}中包含的文件
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div v-for="item in detail?.files" :key="item.id" class="flex items-center justify-between border-b-[1px] border-b-[#eee] border-b-solid py-[10px]">
|
||||||
|
<!-- <img src="~/assets/images/avater.png" alt="" srcset="" class="h-30px w-30px" /> -->
|
||||||
|
<div>
|
||||||
|
<!-- <span class="ml-[10px] cursor-pointer" @click="handleDownloadPreview(item)">{{ item.title }}</span> -->
|
||||||
|
<span class="ml-[10px]">{{ item.title }}</span>
|
||||||
|
<span v-if="item.size" class="ml-[200px] color-[#999]">{{ item.size || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<el-button
|
||||||
|
v-if="detail?.downloadId || detail?.points === 0"
|
||||||
|
type="text"
|
||||||
|
tag="a"
|
||||||
|
target="download"
|
||||||
|
:href="item.url"
|
||||||
|
@click="handleDownloadFile(item.url, item.title)"
|
||||||
|
>
|
||||||
|
下载
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 关联项目 -->
|
||||||
|
<div class="mb-[20px] mt-[34px] flex items-center text-[16px] text-[#333333] font-normal">
|
||||||
|
<div class="h-[24px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div
|
||||||
|
><span class="ml-[10px]">关联{{ detail?.type === 1 ? '图纸' : detail?.type === 2 ? '文本' : '模型' }}</span></div
|
||||||
|
>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col v-for="(item, index) in detail?.relationDraws" :key="index" :span="12">
|
||||||
|
<CardPicture :item-info="item" />
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-empty v-if="!detail?.relationDraws?.length" description="暂无数据"></el-empty>
|
||||||
|
<!-- 关联模型 -->
|
||||||
|
<div class="mb-[20px] mt-[34px] flex items-center text-[16px] text-[#333333] font-normal">
|
||||||
|
<div class="h-[24px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div
|
||||||
|
><span class="ml-[10px]">相关{{ detail?.type === 1 ? '图纸' : detail?.type === 2 ? '文本' : '模型' }}推荐</span></div
|
||||||
|
>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col v-for="(item, index) in relationRecommend" :key="index" :span="12">
|
||||||
|
<CardPicture :item-info="item" />
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<!-- 评论 -->
|
||||||
|
<CommentSection :relation-id="detail!.id" :project-id="detail!.projectId" />
|
||||||
|
</div>
|
||||||
|
<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="mb-[10px]">图纸ID: {{ detail?.id }}</div>
|
||||||
|
<div class="mb-[10px]">文件大小:{{ detail?.filesInfo?.fileSize || 0 }} </div>
|
||||||
|
<!-- <div class="mb-10px">图纸版本:{{ detail.editionsName }} </div> -->
|
||||||
|
<div class="mb-[10px]">图纸格式:{{ detail?.formatType?.toString() }}</div>
|
||||||
|
<div class="mb-[10px]">所需金币:{{ detail?.points }}金币</div>
|
||||||
|
<div class="mb-[10px]">发布时间:{{ dayjs(detail?.createTime).format('YYYY-MM-DD HH:mm:ss') }}</div>
|
||||||
|
<div class="mb-[10px]">图纸参数:{{ detail?.editTypeName }}</div>
|
||||||
|
<div class="mb-[10px]">图纸分类:{{ detail?.projectTypeName }}</div>
|
||||||
|
<div class="mb-[10px]">软件分类:{{ detail?.editionsName }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="mt-[20px] w-[398px] border border-[#EEEEEE] border-rd-[10px_10px_0px_0px] border-solid bg-[#FFFFFF]">
|
||||||
|
<img src="~/assets/images/banner.png" alt="" srcset="" class="w-[100%]" />
|
||||||
|
<div class="box-border border border-[#EEEEEE] border-rd-[10px_10px_0px_0px] border-solid border-t-none bg-[#FFFFFF] pa-[18px]">
|
||||||
|
<div class="flex flex-wrap items-start">
|
||||||
|
<div v-if="userInfo.nickname" class="text-[18px] text-[#333333] font-bold">{{ userInfo.nickname }}</div>
|
||||||
|
<div
|
||||||
|
v-for="item in userInfo.labels"
|
||||||
|
:key="item"
|
||||||
|
class="mb-[10px] ml-[10px] box-border border border-[#1A65FF] rounded-[13px] border-solid px-[8px] py-[3px] color-[#1a65ff]"
|
||||||
|
>{{ item }}</div
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div v-if="userInfo.description" class="mb-[20px] text-[14px] text-[#333333] font-normal">{{ userInfo.description }}</div>
|
||||||
|
<!-- 显示作品 粉丝 荣誉证书 -->
|
||||||
|
<div class="flex items-center gap-[40px]">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="h-[20px]">
|
||||||
|
<img src="~/assets/images/folder.png" alt="works" class="w-[80%]" />
|
||||||
|
</div>
|
||||||
|
<div class="ml-[8px] mt-[-4px] text-[14px] text-[#666] font-normal">作品: {{ userInfo.projectCount || 0 }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="h-[20px]">
|
||||||
|
<img src="~/assets/images/user4.png" alt="fans" class="w-[80%] rounded-full vertical-top" />
|
||||||
|
</div>
|
||||||
|
<div class="relative top-[-3px] ml-[8px] text-[14px] text-[#666] font-normal">粉丝: {{ userInfo.fansCount || 0 }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 3个图片一排 超过换下一行 -->
|
||||||
|
<div v-if="userInfo.files?.length" class="mt-[20px] flex flex-wrap gap-[16px]">
|
||||||
|
<div v-for="i in userInfo.files" :key="i" class="flex-1">
|
||||||
|
<div
|
||||||
|
class="box-border h-[200px] w-full overflow-hidden border border-[#E5E7EB] rounded-[8px] border-solid from-[#FFFFFF] to-[#F5F7FA] bg-gradient-to-b p-[16px]"
|
||||||
|
>
|
||||||
|
<el-image :src="i.url" fit="cover" alt="" srcset="" class="h-full object-cover" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-[20px] h-[1px] w-[336px] rounded-[1px] bg-[#EEEEEE]"></div>
|
||||||
|
<div class="mt-[20px] flex items-center">
|
||||||
|
<div class="h-[24px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div>
|
||||||
|
<span class="ml-[10px] text-[16px]">最新发布</span>
|
||||||
|
</div>
|
||||||
|
<div class="mt-[10px]">
|
||||||
|
<div
|
||||||
|
v-for="item in mainWork"
|
||||||
|
:key="item.id"
|
||||||
|
class="flex cursor-pointer items-center justify-between px-[10px] py-[10px] hover:bg-[#f5f5f5]"
|
||||||
|
@click="handleClick(item.id)"
|
||||||
|
>
|
||||||
|
<div class="ellipsis text-[15px] text-[#333333] font-normal">{{ item.title }}</div>
|
||||||
|
<span class="ml-[10px] flex-shrink-0 color-[#999999]">{{ dayjs(item.createTime).format('MM-DD') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
import { downloadFile } from '~/utils/utils'
|
||||||
|
import { useMessage } from '~/utils/useMessage'
|
||||||
|
import { Warning } from '@element-plus/icons-vue'
|
||||||
|
import SeoHead from '~/components/seo-head/index.vue'
|
||||||
|
import CardPicture from '~/components/kl-card-picture/index.vue'
|
||||||
|
import { getDetail, getRelationRecommend, report, getUserInfo, getMainWork, createContent, createUserProject, deleteProject } from '~/api/drawe-detail/index'
|
||||||
|
import KlNavTab from '~/components/kl-nav-tab/index.vue'
|
||||||
|
import ThumBnail from './components/swiper.vue'
|
||||||
|
import CommentSection from '~/components/comment-section/index.vue'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { onMounted } from 'vue'
|
||||||
|
import type { ProjectRespVO, ProjectDrawPageRespVO, UserExtendSimpleRespDTO, ProjectDrawMemberRespVO } from '~/api/drawe-detail/types'
|
||||||
|
import useUserStore from '~/stores/user'
|
||||||
|
const message = useMessage()
|
||||||
|
const userStore = useUserStore()
|
||||||
|
// 获取路由参数
|
||||||
|
const route = useRoute()
|
||||||
|
const id = route.params.id as string
|
||||||
|
|
||||||
|
// 获取详情
|
||||||
|
// const detail = ref<ProjectRespVO>({} as ProjectRespVO)
|
||||||
|
|
||||||
|
const { data: detail, refresh: refreshDetail } = await useAsyncData(`getDetail${id}`, async () => {
|
||||||
|
const res = await getDetail({ id })
|
||||||
|
return res.data
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log('==', detail.value)
|
||||||
|
|
||||||
|
if (!detail.value) {
|
||||||
|
throw createError({
|
||||||
|
statusCode: 404,
|
||||||
|
statusMessage: 'Page Not Found',
|
||||||
|
fatal: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// const init = () => {
|
||||||
|
// getDetail({ id }).then((res) => {
|
||||||
|
// if (res.code === 0) {
|
||||||
|
// detail.value = res.data
|
||||||
|
// // 获取推荐信息
|
||||||
|
// getRelationRecommendList()
|
||||||
|
// // 获取用户信息
|
||||||
|
// handleGetUserInfo()
|
||||||
|
// // 最新发布
|
||||||
|
// handleGetMainWork()
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
// init()
|
||||||
|
|
||||||
|
const [{ data: mainWork }, { data: userInfo }, { data: relationRecommend }] = await Promise.all([
|
||||||
|
getMainWork({ id: detail.value?.id, limit: 10, memberId: detail.value?.ownedUserId }),
|
||||||
|
getUserInfo({ id: detail.value?.id }),
|
||||||
|
getRelationRecommend({ type: detail.value?.type, projectType: detail.value?.projectType[0] }),
|
||||||
|
])
|
||||||
|
|
||||||
|
// 获取最新发布
|
||||||
|
// const mainWork = ref<ProjectDrawMemberRespVO[]>([])
|
||||||
|
// const handleGetMainWork = () => {
|
||||||
|
// getMainWork({ id: detail.value?.id, limit: 10, memberId: detail.value?.ownedUserId }).then((res) => {
|
||||||
|
// if (res.code === 0) {
|
||||||
|
// mainWork.value = res.data
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// 获取用户信息
|
||||||
|
// const userInfo = ref<UserExtendSimpleRespDTO>({} as UserExtendSimpleRespDTO)
|
||||||
|
// const handleGetUserInfo = () => {
|
||||||
|
// getUserInfo({ id: detail.value?.id }).then((res) => {
|
||||||
|
// if (res.code === 0) {
|
||||||
|
// userInfo.value = res.data
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 获取关联推荐
|
||||||
|
// const relationRecommend = ref<ProjectDrawPageRespVO[]>([])
|
||||||
|
// const getRelationRecommendList = () => {
|
||||||
|
// getRelationRecommend({ type: detail.value?.type, projectType: detail.value?.projectType[0] }).then((res) => {
|
||||||
|
// if (res.code === 0) {
|
||||||
|
// relationRecommend.value = res.data
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
const handleDownloadPreview = (item: any) => {
|
||||||
|
// 预览pdf
|
||||||
|
navigateTo(`/pdf-preview?url=${item.url}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取下载类型 */
|
||||||
|
const getType = (type: number) => {
|
||||||
|
if (type === 1 || type === 2 || type === 3) {
|
||||||
|
// 图纸 文本 模型都传1
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
// 工具箱传
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDownload = async () => {
|
||||||
|
if (!userStore.token) {
|
||||||
|
ElMessage.error('请先登录')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (detail.value?.points === 0) {
|
||||||
|
scrollTo()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (detail.value?.downloadId) {
|
||||||
|
ElMessage.success('您已获取下载权限')
|
||||||
|
scrollTo()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await message.confirm(`是否花费${detail.value?.points}金币下载此资源,是否继续?`, '提示')
|
||||||
|
if (res) {
|
||||||
|
createUserProject({ relationId: detail.value?.id, type: getType(detail.value?.type as number) }).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
ElMessage.success('获取下载权限成功')
|
||||||
|
detail.value!.downloadId = res.data
|
||||||
|
scrollTo()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const scrollTo = () => {
|
||||||
|
const element = document.getElementById('section1')
|
||||||
|
if (element) {
|
||||||
|
element.scrollIntoView({
|
||||||
|
behavior: 'smooth',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleReport = () => {
|
||||||
|
if (!userStore.token) {
|
||||||
|
ElMessage.error('请先登录')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log('举报')
|
||||||
|
ElMessageBox.prompt('说明内容', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
inputPlaceholder: '请输入举报内容',
|
||||||
|
inputErrorMessage: '请输入举报内容',
|
||||||
|
}).then(({ value }) => {
|
||||||
|
report({
|
||||||
|
id: detail.value?.id,
|
||||||
|
title: detail.value?.title,
|
||||||
|
files: detail.value?.files,
|
||||||
|
comments: value,
|
||||||
|
projectId: detail.value?.projectId,
|
||||||
|
drawId: detail.value?.id,
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
ElMessage.success('举报成功')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCollect = async () => {
|
||||||
|
if (!userStore.token) {
|
||||||
|
ElMessage.error('请先登录')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = detail.value?.favoriteId
|
||||||
|
? await deleteProject({ id: detail.value.favoriteId })
|
||||||
|
: await createContent({
|
||||||
|
projectId: detail.value?.projectId,
|
||||||
|
drawId: detail.value?.id,
|
||||||
|
})
|
||||||
|
if (res.code === 0) {
|
||||||
|
ElMessage.success(`${detail.value?.favoriteId ? '取消' : '收藏'}成功`)
|
||||||
|
refreshDetail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClick = (id: string | number) => {
|
||||||
|
navigateTo(`/down-drawe-detail/${id}`) // 修改为在新窗口打开
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDownloadFile = (url: string, name: string) => {
|
||||||
|
downloadFile(url, name)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -1,64 +1,32 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="box-border h-631px w-1019px border border-[#EEEEEE] rounded-12px border-solid bg-[#FFFFFF] pa-30px">
|
<div class="box-border h-[631px] w-[1019px] border border-[#EEEEEE] rounded-[12px] border-solid bg-[#FFFFFF] pa-[30px]">
|
||||||
<swiper
|
<div style="--swiper-navigation-color: #fff; --swiper-pagination-color: #fff" class="swiper mySwiper2">
|
||||||
:style="{
|
<div class="swiper-wrapper">
|
||||||
'--swiper-navigation-color': '#666',
|
<div class="swiper-slide" v-for="(item, index) in props.data" :key="index">
|
||||||
'--swiper-pagination-color': '#666',
|
<img :src="item.url" />
|
||||||
}"
|
</div>
|
||||||
:space-between="10"
|
</div>
|
||||||
disabled-class=""
|
<div class="swiper-button-next"></div>
|
||||||
:thumbs="{ swiper: thumbsSwiper }"
|
<div class="swiper-button-prev"></div>
|
||||||
:modules="modules"
|
</div>
|
||||||
class="mySwiper2"
|
</div>
|
||||||
@swiper="onSwiper"
|
<div class="mb-[20px] mt-[34px] flex items-center text-[16px] text-[#333333] font-normal">
|
||||||
@slide-change="changeSwiper"
|
<div class="h-[24px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div>
|
||||||
>
|
<span class="ml-[10px]">{{ props.type === 1 ? '图纸' : props.type === 2 ? '文本' : '模型' }}</span>
|
||||||
<swiper-slide v-for="(item, index) in props.data" :key="index"><el-image fit="cover" :src="item.url" /></swiper-slide>
|
</div>
|
||||||
<div class="swiper-button-prev color-#fff" @click="handlePrev"></div
|
<div class="box-border h-[126px] w-[1019px] border border-[#EEEEEE] rounded-[6px] border-solid bg-[#FFFFFF] pa-[23px]">
|
||||||
><!--左箭头。如果放置在swiper外面,需要自定义样式。-->
|
<div thumbsSlider="" class="swiper mySwiper">
|
||||||
<div class="swiper-button-next color-#fff" @click="handleNext"></div
|
<div class="swiper-wrapper">
|
||||||
><!--右箭头。如果放置在swiper外面,需要自定义样式。-->
|
<div class="swiper-slide" v-for="(item, index) in props.data" :key="index">
|
||||||
</swiper>
|
<img :src="item.url" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-20px mt-34px flex items-center text-16px text-[#333333] font-normal">
|
|
||||||
<div class="h-24px w-4px rounded-1px bg-[#1A65FF]"></div
|
|
||||||
><span class="ml-10px">{{ props.type === 1 ? '图纸' : props.type === 2 ? '文本' : '模型' }}</span></div
|
|
||||||
>
|
|
||||||
<div class="box-border h-126px w-1019px border border-[#EEEEEE] rounded-6px border-solid bg-[#FFFFFF] pa-23px">
|
|
||||||
<swiper
|
|
||||||
:space-between="10"
|
|
||||||
:slides-per-view="4"
|
|
||||||
:free-mode="true"
|
|
||||||
:watch-slides-progress="true"
|
|
||||||
:modules="modules"
|
|
||||||
class="mySwiper"
|
|
||||||
@swiper="setThumbsSwiper"
|
|
||||||
>
|
|
||||||
<swiper-slide v-for="(item, index) in props.data" :key="index">
|
|
||||||
<div class="Thumbs">
|
|
||||||
<el-image fit="cover" :src="item.url" />
|
|
||||||
</div>
|
</div>
|
||||||
</swiper-slide>
|
|
||||||
</swiper>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { PropType} from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import { ref, watch, nextTick } from 'vue'
|
import { ref, watch, nextTick, onMounted } from 'vue'
|
||||||
// @ts-ignore
|
|
||||||
import { Swiper, SwiperSlide } from 'swiper/vue'
|
|
||||||
|
|
||||||
import 'swiper/css'
|
|
||||||
|
|
||||||
import 'swiper/css/free-mode'
|
|
||||||
import 'swiper/css/navigation'
|
|
||||||
import 'swiper/css/thumbs'
|
|
||||||
|
|
||||||
// import required modules
|
|
||||||
// @ts-ignore
|
|
||||||
import { FreeMode, Navigation, Thumbs } from 'swiper/modules'
|
|
||||||
|
|
||||||
const modules = [FreeMode, Navigation, Thumbs]
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: {
|
data: {
|
||||||
@ -71,50 +39,27 @@
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['changeSwiper', 'nextSwiper'])
|
onMounted(() => {
|
||||||
|
// Initialize Swiper
|
||||||
const thumbsSwiper = ref<any>(null)
|
// @ts-ignore
|
||||||
const useSwiper = ref<any>(null)
|
var swiper = new Swiper('.mySwiper', {
|
||||||
const activeIndex = ref<number>(0)
|
spaceBetween: 10,
|
||||||
|
slidesPerView: 4,
|
||||||
watch(
|
freeMode: true,
|
||||||
() => props.data,
|
watchSlidesProgress: true,
|
||||||
(value) => {
|
})
|
||||||
if (value.length) {
|
// @ts-ignore
|
||||||
nextTick(() => {
|
var swiper2 = new Swiper('.mySwiper2', {
|
||||||
const thumb_active = document.querySelector(`.mySwiper .swiper-slide`)
|
spaceBetween: 10,
|
||||||
thumb_active?.classList.add('swiper-slide-thumb-active')
|
navigation: {
|
||||||
|
nextEl: '.swiper-button-next',
|
||||||
|
prevEl: '.swiper-button-prev',
|
||||||
|
},
|
||||||
|
thumbs: {
|
||||||
|
swiper: swiper,
|
||||||
|
},
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const setThumbsSwiper = (swiper: any) => {
|
|
||||||
thumbsSwiper.value = swiper
|
|
||||||
}
|
|
||||||
|
|
||||||
const handlePrev = () => {
|
|
||||||
if (activeIndex.value === 0 || props.data.length === 0) {
|
|
||||||
emit('nextSwiper', false)
|
|
||||||
}
|
|
||||||
useSwiper.value.slidePrev()
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleNext = () => {
|
|
||||||
if (activeIndex.value === props.data.length - 1 || props.data.length === 0) {
|
|
||||||
emit('nextSwiper', true)
|
|
||||||
}
|
|
||||||
useSwiper.value.slideNext()
|
|
||||||
}
|
|
||||||
|
|
||||||
const onSwiper = (swiper: any) => {
|
|
||||||
useSwiper.value = swiper
|
|
||||||
}
|
|
||||||
|
|
||||||
const changeSwiper = (e: any) => {
|
|
||||||
activeIndex.value = e.activeIndex
|
|
||||||
emit('changeSwiper', e.activeIndex)
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@ -210,4 +155,9 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.swiper-button-next,
|
||||||
|
.swiper-button-prev {
|
||||||
|
color: #666 !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,350 +0,0 @@
|
|||||||
<template>
|
|
||||||
<KlNavTab />
|
|
||||||
<div class="ml-auto mr-auto mt-20px w1440">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<div class="box-border h-60px w-1019px flex items-center justify-between border border-[#EEEEEE] rounded-12px border-solid bg-[#FFFFFF] px-27px py-24px">
|
|
||||||
<div class="text-20px text-[#333333] font-normal"> {{ detail.title }}</div>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<img :src="detail.ownedUserIdInfo?.avatar" alt="" srcset="" class="h-30px w-30px rd-50%" />
|
|
||||||
<span class="ml-12px color-#999999">by {{ detail.ownedUserIdInfo?.nickName }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="ml-23px flex flex-1 text-18px text-[#FFFFFF] font-normal">
|
|
||||||
<div class="h-60px w-160px flex cursor-pointer items-center justify-center rounded-8px bg-[#1A65FF]" @click="handleDownload">
|
|
||||||
<img src="~/assets/images/download.png" alt="" srcset="" class="mr-4px h-22px w-27px" />
|
|
||||||
{{ detail.points === 0 ? '免费下载' : '立即下载' }}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="!detail.favoriteId"
|
|
||||||
class="ml-11px h-60px flex flex-1 cursor-pointer items-center justify-center rounded-8px bg-[#E7B03B]"
|
|
||||||
@click="handleCollect"
|
|
||||||
><img src="~/assets/images/collect.png" alt="" srcset="" class="mr-4px h-24px w-24px" /> 收藏</div
|
|
||||||
>
|
|
||||||
<div v-else class="ml-11px h-60px flex flex-1 cursor-pointer items-center justify-center rounded-8px bg-[#E7B03B]" @click="handleCollect"
|
|
||||||
><img src="~/assets/images/wjx2.png" alt="" srcset="" class="mr-4px h-18px w-18px" /> 已收藏</div
|
|
||||||
>
|
|
||||||
|
|
||||||
<div class="ml-11px h-60px flex flex-1 cursor-pointer items-center justify-center rounded-8px bg-[#F56C6C]" @click="handleReport"
|
|
||||||
><el-icon class="mr-4px mt-4px"><Warning /></el-icon> 举报</div
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- -->
|
|
||||||
<div class="ma-auto mt-21px flex">
|
|
||||||
<div class="w-1019px">
|
|
||||||
<div>
|
|
||||||
<ThumBnail :data="detail.coverImages" :type="detail.type" @change-swiper="changeSwiper" @next-swiper="nextSwiper"></ThumBnail>
|
|
||||||
</div>
|
|
||||||
<div class="mb-20px mt-34px flex items-center text-16px text-[#333333] font-normal">
|
|
||||||
<div class="h-24px w-4px rounded-1px bg-[#1A65FF]"></div><span class="ml-10px">{{ detail.title }}描述</span></div
|
|
||||||
>
|
|
||||||
<div class="box-border min-h-90px w-1019px border border-[#EEEEEE] rounded-6px border-solid bg-[#FFFFFF] pa-24px text-14px text-[#333333] font-normal">
|
|
||||||
{{ detail.description }}
|
|
||||||
</div>
|
|
||||||
<div id="section1" class="mb-20px mt-34px flex items-center text-16px text-[#333333] font-normal">
|
|
||||||
<div class="h-24px w-4px rounded-1px bg-[#1A65FF]"></div><span class="ml-10px">{{ detail.title }}附件</span></div
|
|
||||||
>
|
|
||||||
<div 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">
|
|
||||||
{{ detail.type === 1 ? '图纸' : detail.type === 2 ? '文本' : '模型' }}中包含的文件
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div v-for="item in detail.files" :key="item.id" class="flex items-center justify-between border-b-1px border-b-[#eee] border-b-solid py-10px">
|
|
||||||
<!-- <img src="~/assets/images/avater.png" alt="" srcset="" class="h-30px w-30px" /> -->
|
|
||||||
<div>
|
|
||||||
<span class="ml-10px cursor-pointer" @click="handleDownloadPreview(item)">{{ item.title }}</span>
|
|
||||||
<span v-if="item.size" class="ml-200px color-#999">{{ item.size || '-' }}</span>
|
|
||||||
</div>
|
|
||||||
<el-button
|
|
||||||
v-if="detail.downloadId || detail.points === 0"
|
|
||||||
type="text"
|
|
||||||
tag="a"
|
|
||||||
target="download"
|
|
||||||
:href="item.url"
|
|
||||||
@click="handleDownloadFile(item.url, item.title)"
|
|
||||||
>
|
|
||||||
下载
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 关联项目 -->
|
|
||||||
<div class="mb-20px mt-34px flex items-center text-16px text-[#333333] font-normal">
|
|
||||||
<div class="h-24px w-4px rounded-1px bg-[#1A65FF]"></div
|
|
||||||
><span class="ml-10px">关联{{ detail.type === 1 ? '图纸' : detail.type === 2 ? '文本' : '模型' }}</span></div
|
|
||||||
>
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col v-for="(item, index) in detail.relationDraws" :key="index" :span="12">
|
|
||||||
<CardPicture :item-info="item" />
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-empty v-if="!detail.relationDraws?.length" description="暂无数据"></el-empty>
|
|
||||||
<!-- 关联模型 -->
|
|
||||||
<div class="mb-20px mt-34px flex items-center text-16px text-[#333333] font-normal">
|
|
||||||
<div class="h-24px w-4px rounded-1px bg-[#1A65FF]"></div
|
|
||||||
><span class="ml-10px">相关{{ detail.type === 1 ? '图纸' : detail.type === 2 ? '文本' : '模型' }}推荐</span></div
|
|
||||||
>
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col v-for="(item, index) in relationRecommend" :key="index" :span="12">
|
|
||||||
<CardPicture :item-info="item" />
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<!-- 评论 -->
|
|
||||||
<CommentSection :relation-id="detail.id" :project-id="detail.projectId" />
|
|
||||||
</div>
|
|
||||||
<div class="ml-22px">
|
|
||||||
<div class="box-border 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">文件大小:{{ detail.filesInfo?.fileSize || 0 }} </div>
|
|
||||||
<!-- <div class="mb-10px">图纸版本:{{ detail.editionsName }} </div> -->
|
|
||||||
<div class="mb-10px">图纸格式:{{ detail.formatType?.toString() }}</div>
|
|
||||||
<div class="mb-10px">所需金币:{{ detail.points }}金币</div>
|
|
||||||
<div class="mb-10px">发布时间:{{ dayjs(detail.createTime).format('YYYY-MM-DD HH:mm:ss') }}</div>
|
|
||||||
<div class="mb-10px">图纸参数:{{ detail.editTypeName }}</div>
|
|
||||||
<div class="mb-10px">图纸分类:{{ detail.projectTypeName }}</div>
|
|
||||||
<div class="mb-10px">软件分类:{{ detail.editionsName }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="mt-20px w-398px border border-[#EEEEEE] border-rd-[10px_10px_0px_0px] border-solid bg-[#FFFFFF]">
|
|
||||||
<img src="~/assets/images/banner.png" alt="" srcset="" class="w-100%" />
|
|
||||||
<div class="box-border border border-[#EEEEEE] border-rd-[10px_10px_0px_0px] border-solid border-t-none bg-[#FFFFFF] pa-18px">
|
|
||||||
<div class="flex flex-wrap items-start">
|
|
||||||
<div v-if="userInfo.nickname" class="mt-10px text-18px text-[#333333] font-bold">{{ userInfo.nickname }}</div>
|
|
||||||
<div
|
|
||||||
v-for="item in userInfo.labels"
|
|
||||||
:key="item"
|
|
||||||
class="mb-10px ml-10px box-border border border-[#1A65FF] rounded-13px border-solid px-8px py-3px color-#1a65ff"
|
|
||||||
>{{ item }}</div
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<div v-if="userInfo.description" class="mb-20px text-14px text-[#333333] font-normal">{{ userInfo.description }}</div>
|
|
||||||
<!-- 显示作品 粉丝 荣誉证书 -->
|
|
||||||
<div class="flex items-center gap-40px">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<div class="h-20px">
|
|
||||||
<img src="~/assets/images/folder.png" alt="works" class="w-80%" />
|
|
||||||
</div>
|
|
||||||
<div class="ml-8px mt--4px text-14px text-[#666] font-normal">作品: {{ userInfo.projectCount || 0 }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<div class="h-20px">
|
|
||||||
<img src="~/assets/images/user4.png" alt="fans" class="w-80% rounded-full vertical-top" />
|
|
||||||
</div>
|
|
||||||
<div class="relative top--3px ml-8px text-14px text-[#666] font-normal">粉丝: {{ userInfo.fansCount || 0 }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 3个图片一排 超过换下一行 -->
|
|
||||||
<div v-if="userInfo.files?.length" class="mt-20px flex flex-wrap gap-16px">
|
|
||||||
<div v-for="i in userInfo.files" :key="i" class="flex-1">
|
|
||||||
<div
|
|
||||||
class="box-border h-200px w-full overflow-hidden border border-[#E5E7EB] rounded-8px border-solid from-[#FFFFFF] to-[#F5F7FA] bg-gradient-to-b p-16px"
|
|
||||||
>
|
|
||||||
<el-image :src="i.url" fit="cover" alt="" srcset="" class="h-full object-cover" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-20px h-1px w-336px rounded-1px bg-[#EEEEEE]"></div>
|
|
||||||
<div class="mt-20px flex items-center">
|
|
||||||
<div class="h-24px w-4px rounded-1px bg-[#1A65FF]"></div>
|
|
||||||
<span class="ml-10px text-16px">最新发布</span>
|
|
||||||
</div>
|
|
||||||
<div class="mt-10px">
|
|
||||||
<div
|
|
||||||
v-for="item in mainWork"
|
|
||||||
:key="item.id"
|
|
||||||
class="flex cursor-pointer items-center justify-between px-10px py-10px hover:bg-#f5f5f5"
|
|
||||||
@click="handleClick(item.id)"
|
|
||||||
>
|
|
||||||
<div class="ellipsis text-15px text-[#333333] font-normal">{{ item.title }}</div>
|
|
||||||
<span class="ml-10px flex-shrink-0 color-#999999">{{ dayjs(item.createTime).format('MM-DD') }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import dayjs from 'dayjs'
|
|
||||||
import { downloadFile } from '~/utils/utils'
|
|
||||||
import { useMessage } from '~/utils/useMessage'
|
|
||||||
import { Warning } from '@element-plus/icons-vue'
|
|
||||||
import CardPicture from '~/components/kl-card-picture/index.vue'
|
|
||||||
import { getDetail, getRelationRecommend, report, getUserInfo, getMainWork, createContent, createUserProject, deleteProject } from '~/api/drawe-detail/index'
|
|
||||||
import KlNavTab from '~/components/kl-nav-tab/index.vue'
|
|
||||||
import ThumBnail from './components/swiper.vue'
|
|
||||||
import CommentSection from '~/components/comment-section/index.vue'
|
|
||||||
import { useRoute } from 'vue-router'
|
|
||||||
import { ref } from 'vue'
|
|
||||||
import type { ProjectRespVO, ProjectDrawPageRespVO, UserExtendSimpleRespDTO, ProjectDrawMemberRespVO } from '~/api/drawe-detail/types'
|
|
||||||
import useUserStore from '~/store/user'
|
|
||||||
const message = useMessage()
|
|
||||||
const userStore = useUserStore()
|
|
||||||
// 获取路由参数
|
|
||||||
const route = useRoute()
|
|
||||||
const id = route.query.id as string
|
|
||||||
|
|
||||||
// 获取详情
|
|
||||||
const detail = ref<ProjectRespVO>({} as ProjectRespVO)
|
|
||||||
const init = () => {
|
|
||||||
getDetail({ id }).then((res) => {
|
|
||||||
if (res.code === 0) {
|
|
||||||
detail.value = res.data
|
|
||||||
// 获取推荐信息
|
|
||||||
getRelationRecommendList()
|
|
||||||
// 获取用户信息
|
|
||||||
handleGetUserInfo()
|
|
||||||
// 最新发布
|
|
||||||
handleGetMainWork()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
init()
|
|
||||||
|
|
||||||
// 获取最新发布
|
|
||||||
const mainWork = ref<ProjectDrawMemberRespVO[]>([])
|
|
||||||
const handleGetMainWork = () => {
|
|
||||||
getMainWork({ id: detail.value.id, limit: 10, memberId: detail.value.ownedUserId }).then((res) => {
|
|
||||||
if (res.code === 0) {
|
|
||||||
mainWork.value = res.data
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 获取用户信息
|
|
||||||
const userInfo = ref<UserExtendSimpleRespDTO>({} as UserExtendSimpleRespDTO)
|
|
||||||
const handleGetUserInfo = () => {
|
|
||||||
getUserInfo({ id: detail.value.id }).then((res) => {
|
|
||||||
if (res.code === 0) {
|
|
||||||
userInfo.value = res.data
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取关联推荐
|
|
||||||
const relationRecommend = ref<ProjectDrawPageRespVO[]>([])
|
|
||||||
const getRelationRecommendList = () => {
|
|
||||||
getRelationRecommend({ type: detail.value.type, projectType: detail.value.projectType[0] }).then((res) => {
|
|
||||||
if (res.code === 0) {
|
|
||||||
relationRecommend.value = res.data
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const changeSwiper = (index: number) => {
|
|
||||||
console.log(index)
|
|
||||||
}
|
|
||||||
|
|
||||||
const nextSwiper = (val: any) => {
|
|
||||||
console.log(val)
|
|
||||||
}
|
|
||||||
const handleDownloadPreview = (item: any) => {
|
|
||||||
// 预览pdf
|
|
||||||
navigateTo(`/pdf-preview?url=${item.url}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 获取下载类型 */
|
|
||||||
const getType = (type: number) => {
|
|
||||||
if (type === 1 || type === 2 || type === 3) {
|
|
||||||
// 图纸 文本 模型都传1
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
// 工具箱传
|
|
||||||
return 2
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleDownload = async () => {
|
|
||||||
if (!userStore.token) {
|
|
||||||
ElMessage.error('请先登录')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (detail.value.points === 0) {
|
|
||||||
scrollTo()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (detail.value.downloadId) {
|
|
||||||
ElMessage.success('您已获取下载权限')
|
|
||||||
scrollTo()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = await message.confirm(`是否花费${detail.value.points}金币下载此资源,是否继续?`, '提示')
|
|
||||||
if (res) {
|
|
||||||
createUserProject({ relationId: detail.value.id, type: getType(detail.value.type) }).then((res) => {
|
|
||||||
if (res.code === 0) {
|
|
||||||
ElMessage.success('获取下载权限成功')
|
|
||||||
detail.value.downloadId = res.data
|
|
||||||
scrollTo()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const scrollTo = () => {
|
|
||||||
const element = document.getElementById('section1')
|
|
||||||
if (element) {
|
|
||||||
element.scrollIntoView({
|
|
||||||
behavior: 'smooth',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleReport = () => {
|
|
||||||
if (!userStore.token) {
|
|
||||||
ElMessage.error('请先登录')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
console.log('举报')
|
|
||||||
ElMessageBox.prompt('说明内容', '提示', {
|
|
||||||
confirmButtonText: '确定',
|
|
||||||
cancelButtonText: '取消',
|
|
||||||
inputPlaceholder: '请输入举报内容',
|
|
||||||
inputErrorMessage: '请输入举报内容',
|
|
||||||
}).then(({ value }) => {
|
|
||||||
report({
|
|
||||||
id: detail.value.id,
|
|
||||||
title: detail.value.title,
|
|
||||||
files: detail.value.files,
|
|
||||||
comments: value,
|
|
||||||
projectId: detail.value.projectId,
|
|
||||||
drawId: detail.value.id,
|
|
||||||
}).then((res) => {
|
|
||||||
if (res.code === 0) {
|
|
||||||
ElMessage.success('举报成功')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleCollect = async () => {
|
|
||||||
if (!userStore.token) {
|
|
||||||
ElMessage.error('请先登录')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = detail.value.favoriteId
|
|
||||||
? await deleteProject({ id: detail.value.favoriteId })
|
|
||||||
: await createContent({
|
|
||||||
projectId: detail.value.projectId,
|
|
||||||
drawId: detail.value.id,
|
|
||||||
})
|
|
||||||
if (res.code === 0) {
|
|
||||||
ElMessage.success(`${detail.value.favoriteId ? '取消' : '收藏'}成功`)
|
|
||||||
init()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleClick = (id: string | number) => {
|
|
||||||
navigateTo(`/down-drawe-detail?id=${id}`) // 修改为在新窗口打开
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleDownloadFile = (url: string, name: string) => {
|
|
||||||
downloadFile(url, name)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@ -0,0 +1,126 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 导航 -->
|
||||||
|
<SeoHead title="工程设计图纸下载_CAD设计图纸资源库" />
|
||||||
|
<KlNavTab active="图纸" :type="1" />
|
||||||
|
<div class="ma-auto w-[1440px]">
|
||||||
|
<!-- 图纸分类 -->
|
||||||
|
<KlWallpaperCategory v-model="query" v-model:level="level" :type="1" />
|
||||||
|
<!-- 推荐栏目 -->
|
||||||
|
<RecommendedColumnsV2 v-model="query" v-model:result="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="[12, 24, 48]"
|
||||||
|
:total="result?.total"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
@size-change="handleClickSize"
|
||||||
|
@current-change="handeClickCurrent"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import KlNavTab from '~/components/kl-nav-tab/index.vue'
|
||||||
|
import KlWallpaperCategory from '~/components/kl-wallpaper-category/index.vue'
|
||||||
|
import RecommendedColumnsV2 from '~/components/drawe-components/RecommendedColumnsV2.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 handleClickSize = (val: number) => {
|
||||||
|
query.value.pageSize = val
|
||||||
|
// getPage()
|
||||||
|
navigateTo(`/drawe/${query.value.projectType}/${query.value.pageNo}/${val}/${query.value.editions}/${query.value.source}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handeClickCurrent = (val: number) => {
|
||||||
|
query.value.pageNo = val
|
||||||
|
// getPage()
|
||||||
|
navigateTo(`/drawe/${query.value.projectType}/${val}/${query.value.pageSize}/${query.value.editions}/${query.value.source}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
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}`,
|
||||||
|
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(`/drawe/${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>
|
||||||
@ -1,7 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- 导航 -->
|
<!-- 导航 -->
|
||||||
|
<SeoHead title="工程设计图纸下载_CAD设计图纸资源库" />
|
||||||
<KlNavTab active="图纸" :type="1" />
|
<KlNavTab active="图纸" :type="1" />
|
||||||
<div class="ma-auto w-1440px">
|
<div class="ma-auto w-[1440px]">
|
||||||
<!-- 图纸分类 -->
|
<!-- 图纸分类 -->
|
||||||
<KlWallpaperCategory v-model="query" v-model:level="level" :type="1" />
|
<KlWallpaperCategory v-model="query" v-model:level="level" :type="1" />
|
||||||
<!-- 推荐栏目 -->
|
<!-- 推荐栏目 -->
|
||||||
@ -9,12 +10,12 @@
|
|||||||
<!-- 精选专题 -->
|
<!-- 精选专题 -->
|
||||||
<!-- <FeaturedSpecials></FeaturedSpecials> -->
|
<!-- <FeaturedSpecials></FeaturedSpecials> -->
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<div class="mt-10px flex justify-center">
|
<div class="mt-[10px] flex justify-center">
|
||||||
<el-pagination
|
<el-pagination
|
||||||
v-model:current-page="query.pageNo"
|
v-model:current-page="query.pageNo"
|
||||||
v-model:page-size="query.pageSize"
|
v-model:page-size="query.pageSize"
|
||||||
:page-sizes="[12, 24, 48]"
|
:page-sizes="[12, 24, 48]"
|
||||||
:total="result.total"
|
:total="result?.total"
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
@size-change="handleClickSize"
|
@size-change="handleClickSize"
|
||||||
@current-change="handeClickCurrent"
|
@current-change="handeClickCurrent"
|
||||||
@ -25,70 +26,87 @@
|
|||||||
<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 KlWallpaperCategory from '~/components/kl-wallpaper-category/index.vue'
|
import KlWallpaperCategory from '~/components/kl-wallpaper-category/index.vue'
|
||||||
import RecommendedColumnsV2 from './components/RecommendedColumnsV2.vue'
|
import RecommendedColumnsV2 from '~/components/drawe-components/RecommendedColumnsV2.vue'
|
||||||
// import FeaturedSpecials from './components/FeaturedSpecials.vue'
|
// import FeaturedSpecials from './components/FeaturedSpecials.vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { reactive, watch, ref } from 'vue'
|
import { reactive, watch, ref } from 'vue'
|
||||||
import { page } from '~/api/upnew/index'
|
import { page } from '~/api/upnew/index'
|
||||||
|
import { getDictTree } from '~/api/home/index'
|
||||||
import type { pageRes, pageReq } from '~/api/upnew/types'
|
import type { pageRes, pageReq } from '~/api/upnew/types'
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
const level = ref(
|
const level = ref(
|
||||||
route.query.level
|
route.query?.valuelevel
|
||||||
? JSON.parse(route.query.level as string)
|
? JSON.parse(route.query.valuelevel as string)
|
||||||
: [
|
: [
|
||||||
{
|
{
|
||||||
id: '0',
|
id: -1,
|
||||||
name: '图纸库',
|
name: '图纸库',
|
||||||
isChildren: false,
|
isChildren: false,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
const keywords = ref(route.query.keywords as string)
|
const keywords = ref((route.query?.valuekeywords as string) || '')
|
||||||
|
|
||||||
const query = reactive<pageReq>({
|
const query = ref<pageReq>({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 12,
|
pageSize: 12,
|
||||||
projectType: '',
|
projectType: '-1',
|
||||||
editions: '',
|
editions: '-1',
|
||||||
source: '',
|
source: -1,
|
||||||
type: 1,
|
type: 1,
|
||||||
title: keywords.value,
|
title: keywords.value,
|
||||||
})
|
})
|
||||||
const result = reactive<pageRes>({
|
// const result = reactive<pageRes>({
|
||||||
list: [],
|
// list: [],
|
||||||
total: 0,
|
// total: 0,
|
||||||
})
|
// })
|
||||||
|
|
||||||
// 如果id存在,则设置projectType
|
// 如果id存在,则设置projectType
|
||||||
if (level.value.length) {
|
if (level.value.length) {
|
||||||
query.projectType = level.value[level.value.length - 1].id || ''
|
// query.value.projectType = level.value[level.value.length - 1].id || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleClickSize = (val: number) => {
|
const handleClickSize = (val: number) => {
|
||||||
query.pageSize = val
|
query.value.pageSize = val
|
||||||
getPage()
|
// getPage()
|
||||||
|
navigateTo(`/drawe/${query.value.projectType}/${query.value.pageNo}/${val}/${query.value.editions}/${query.value.source}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handeClickCurrent = (val: number) => {
|
const handeClickCurrent = (val: number) => {
|
||||||
query.pageNo = val
|
query.value.pageNo = val
|
||||||
getPage()
|
// getPage()
|
||||||
|
navigateTo(`/drawe/${query.value.projectType}/${val}/${query.value.pageSize}/${query.value.editions}/${query.value.source}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getPage = () => {
|
const { data: result, refresh: getPage } = useAsyncData(
|
||||||
page(query).then((res) => {
|
`draw-page-list-${query.value.projectType}-${query.value.editions}-${query.value.source}-${query.value.pageNo}-${query.value.pageSize}-${query.value.title}`,
|
||||||
const { data, code } = res
|
async () => {
|
||||||
if (code === 0) {
|
const res = await page({
|
||||||
result.list = data.list
|
...query.value,
|
||||||
result.total = data.total
|
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
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
getPage()
|
watch([() => query.value.projectType, () => query.value.editions, () => query.value.source], (val) => {
|
||||||
|
|
||||||
watch([() => query.projectType, () => query.editions, () => query.source], (val) => {
|
|
||||||
if (val) {
|
if (val) {
|
||||||
getPage()
|
navigateTo(`/drawe/${query.value.projectType}/1/${query.value.pageSize}/${query.value.editions}/${query.value.source}`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -0,0 +1,128 @@
|
|||||||
|
<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 KlWallpaperCategory from '~/components/kl-wallpaper-category/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>
|
||||||
@ -3,7 +3,7 @@
|
|||||||
<KlNavTab active="国外专区" />
|
<KlNavTab active="国外专区" />
|
||||||
<!-- banneer提示 -->
|
<!-- banneer提示 -->
|
||||||
<BannerTips />
|
<BannerTips />
|
||||||
<div class="ma-auto w-1440px">
|
<div class="ma-auto w-[1440px]">
|
||||||
<!-- 图片展示鼠标移上去展示提示语 -->
|
<!-- 图片展示鼠标移上去展示提示语 -->
|
||||||
<!-- <ImageTips /> -->
|
<!-- <ImageTips /> -->
|
||||||
<!-- 推荐栏目 -->
|
<!-- 推荐栏目 -->
|
||||||
@ -11,12 +11,12 @@
|
|||||||
<!-- 精选专题 -->
|
<!-- 精选专题 -->
|
||||||
<!-- <FeaturedSpecials></FeaturedSpecials> -->
|
<!-- <FeaturedSpecials></FeaturedSpecials> -->
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<div class="mt-10px flex justify-center">
|
<div class="mt-[10px] flex justify-center">
|
||||||
<el-pagination
|
<el-pagination
|
||||||
v-model:current-page="query.pageNo"
|
v-model:current-page="query.pageNo"
|
||||||
v-model:page-size="query.pageSize"
|
v-model:page-size="query.pageSize"
|
||||||
:page-sizes="[10, 20, 30]"
|
:page-sizes="[10, 20, 30]"
|
||||||
:total="result.total"
|
:total="result?.total"
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
@size-change="handleChangeSize"
|
@size-change="handleChangeSize"
|
||||||
@current-change="handleChangeCurrent"
|
@current-change="handleChangeCurrent"
|
||||||
@ -26,9 +26,9 @@
|
|||||||
</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'
|
||||||
@ -38,42 +38,56 @@
|
|||||||
const query = reactive<pageReq>({
|
const query = reactive<pageReq>({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
projectType: '',
|
projectType: '-1',
|
||||||
editions: '',
|
editions: '-1',
|
||||||
source: '',
|
source: -1,
|
||||||
type: 1,
|
type: 1,
|
||||||
})
|
})
|
||||||
const result = reactive<pageRes>({
|
// const result = reactive<pageRes>({
|
||||||
list: [],
|
// list: [],
|
||||||
total: 0,
|
// total: 0,
|
||||||
})
|
// })
|
||||||
|
|
||||||
const getPage = () => {
|
const { data: result } = await useAsyncData(`draw-page-list-${Date.now()}`, async () => {
|
||||||
page(query).then((res) => {
|
const res = await page({
|
||||||
const { data, code } = res
|
...query,
|
||||||
if (code === 0) {
|
editions: query.editions === '-1' ? '' : query.editions,
|
||||||
result.list = data.list
|
source: query.source === -1 ? '' : query.source,
|
||||||
result.total = data.total
|
projectType: query.projectType === '-1' ? '' : query.projectType,
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
return res.data
|
||||||
|
})
|
||||||
|
// const getPage = () => {
|
||||||
|
// page(query).then((res) => {
|
||||||
|
// const { data, code } = res
|
||||||
|
// if (code === 0) {
|
||||||
|
// result.list = data.list
|
||||||
|
// result.total = data.total
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
getPage()
|
// getPage()
|
||||||
|
|
||||||
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>
|
||||||
|
|||||||
@ -1,63 +1,63 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div>
|
<div>
|
||||||
<div class="my-32px mb-20px text-18px text-[#333333] font-normal flex items-center"><img src="~/assets/images/2.png" alt="" srcset="" class="mr-6px" /> 多多排行榜</div>
|
<div class="my-[32px] mb-[20px] text-[18px] text-[#333333] font-normal flex items-center"><img src="~/assets/images/2.png" alt="" srcset="" class="mr-[6px]" /> 多多排行榜</div>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div class="ma-auto box-border h-470px w-460px border border-[#EEEEEE] rounded-12px border-solid bg-[#FFFFFF] px-28px">
|
<div class="ma-auto box-border h-[470px] w-[460px] border border-[#EEEEEE] rounded-[12px] border-solid bg-[#FFFFFF] px-[28px]">
|
||||||
<div class="title-bg ma-auto mb-40px mt-20px">一周图纸作者排行</div>
|
<div class="title-bg ma-auto mb-[40px] mt-[20px]">一周图纸作者排行</div>
|
||||||
<div v-for="(item, index) in topList" :key="item.ownUserId" class="mb-23px flex items-center">
|
<div v-for="(item, index) in topList" :key="item.ownUserId" class="mb-[23px] flex items-center">
|
||||||
<div class="w-30px text-center"
|
<div class="w-[30px] text-center"
|
||||||
><img
|
><img
|
||||||
v-if="index === 0 || index === 1 || index === 2"
|
v-if="index === 0 || index === 1 || index === 2"
|
||||||
:src="imagesUrl(index)"
|
:src="imagesUrl(index)"
|
||||||
alt=""
|
alt=""
|
||||||
srcset=""
|
srcset=""
|
||||||
:class="index === 0 ? 'w-20px h-22px' : 'w-28px h-29px'"
|
:class="index === 0 ? 'w-[20px] h-[22px]' : 'w-[28px] h-[29px]'"
|
||||||
/>
|
/>
|
||||||
<span v-else class="LiHei (Noncommercial) font-MF text-16px text-[#999999] font-normal">{{ index }}</span>
|
<span v-else class="LiHei (Noncommercial) font-MF text-[16px] text-[#999999] font-normal">{{ index }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-20px w-120px flex items-center text-16px text-[#333333] font-normal">
|
<div class="ml-[20px] w-[120px] flex items-center text-[16px] text-[#333333] font-normal">
|
||||||
<img :src="item?.avatar" alt="" srcset="" class="h-36px w-36px rd-50%" />
|
<img :src="item?.avatar" alt="" srcset="" class="h-[36px] w-[36px] rd-[50%]" />
|
||||||
<span class="ellipsis1 ml-10px">{{ item.nickname }}</span>
|
<span class="ellipsis1 ml-[10px]">{{ item.nickname }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-20px flex text-14px text-[#666666] font-normal">
|
<div class="ml-[20px] flex text-[14px] text-[#666666] font-normal">
|
||||||
<!-- <el-icon class="text-17px color-#a8abb2!"><Folder /></el-icon> -->
|
<!-- <el-icon class="text-17px color-#a8abb2!"><Folder /></el-icon> -->
|
||||||
<img src="~/assets/images/file.png" alt="" srcset="" class="h-18px" />
|
<img src="~/assets/images/file.png" alt="" srcset="" class="h-[18px]" />
|
||||||
<div class="ellipsis1 ml-10px">作品:{{ item.projectCount || 0 }}</div>
|
<div class="ellipsis1 ml-[10px]">作品:{{ item.projectCount || 0 }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-20px flex text-14px text-[#666666] font-normal">
|
<div class="ml-[20px] flex text-[14px] text-[#666666] font-normal">
|
||||||
<!-- <el-icon class="text-17px color-[#e4e7ed!]"><User /></el-icon> -->
|
<!-- <el-icon class="text-17px color-[#e4e7ed!]"><User /></el-icon> -->
|
||||||
<img src="~/assets/images/user4.png" alt="" srcset="" class="h-17px" />
|
<img src="~/assets/images/user4.png" alt="" srcset="" class="h-[17px]" />
|
||||||
<div class="ellipsis1 ml-10px">粉丝:{{ item.fansCount || 0 }}</div>
|
<div class="ellipsis1 ml-[10px]">粉丝:{{ item.fansCount || 0 }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 暂无数据 -->
|
<!-- 暂无数据 -->
|
||||||
<el-empty v-if="!topList.length" description="暂无数据"></el-empty>
|
<el-empty v-if="!topList.length" description="暂无数据"></el-empty>
|
||||||
</div>
|
</div>
|
||||||
<div class="ma-auto ml-18px box-border h-470px w-460px border border-[#EEEEEE] rounded-12px border-solid bg-[#FFFFFF] px-28px">
|
<div class="ma-auto ml-[18px] box-border h-[470px] w-[460px] border border-[#EEEEEE] rounded-[12px] border-solid bg-[#FFFFFF] px-[28px]">
|
||||||
<div class="title-bg ma-auto mb-40px mt-20px">优质上传作者图纸</div>
|
<div class="title-bg ma-auto mb-[40px] mt-[20px]">优质上传作者图纸</div>
|
||||||
<div v-for="(item, index) in userTopList" :key="index" class="mb-23px flex items-center">
|
<div v-for="(item, index) in userTopList" :key="index" class="mb-[23px] flex items-center">
|
||||||
<div class="w-30px text-center"
|
<div class="w-[30px] text-center"
|
||||||
><img
|
><img
|
||||||
v-if="index === 0 || index === 1 || index === 2"
|
v-if="index === 0 || index === 1 || index === 2"
|
||||||
:src="imagesUrl(index)"
|
:src="imagesUrl(index)"
|
||||||
alt=""
|
alt=""
|
||||||
srcset=""
|
srcset=""
|
||||||
:class="index === 0 ? 'w-20px h-22px' : 'w-28px h-29px'"
|
:class="index === 0 ? 'w-[20px] h-[22px]' : 'w-[28px] h-[29px]'"
|
||||||
/>
|
/>
|
||||||
<span v-else class="font-MF LiHei (Noncommercial) text-16px text-[#999999] font-normal">{{ index }}</span>
|
<span v-else class="font-MF LiHei (Noncommercial) text-[16px] text-[#999999] font-normal">{{ index }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-20px w-120px flex items-center text-16px text-[#333333] font-normal">
|
<div class="ml-[20px] w-[120px] flex items-center text-[16px] text-[#333333] font-normal">
|
||||||
<img :src="item?.avatar" alt="" srcset="" class="h-36px w-36px rd-50%" />
|
<img :src="item?.avatar" alt="" srcset="" class="h-[36px] w-[36px] rd-[50%]" />
|
||||||
<span class="ellipsis1 ml-10px">{{ item.nickname }}</span>
|
<span class="ellipsis1 ml-[10px]">{{ item.nickname }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-20px flex text-14px text-[#666666] font-normal">
|
<div class="ml-[20px] flex text-[14px] text-[#666666] font-normal">
|
||||||
<img src="~/assets/images/file.png" alt="" srcset="" class="h-18px" />
|
<img src="~/assets/images/file.png" alt="" srcset="" class="h-[18px]" />
|
||||||
<div class="ellipsis1 ml-10px">作品:{{ item.projectCount || 0 }}</div>
|
<div class="ellipsis1 ml-[10px]">作品:{{ item.projectCount || 0 }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-20px flex text-14px text-[#666666] font-normal">
|
<div class="ml-[20px] flex text-[14px] text-[#666666] font-normal">
|
||||||
<img src="~/assets/images/user4.png" alt="" srcset="" class="h-17px" />
|
<img src="~/assets/images/user4.png" alt="" srcset="" class="h-[17px]" />
|
||||||
<div class="ellipsis1 ml-10px">粉丝:{{ item.fansCount || 0 }}</div>
|
<div class="ellipsis1 ml-[10px]">粉丝:{{ item.fansCount || 0 }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 暂无数据 -->
|
<!-- 暂无数据 -->
|
||||||
@ -65,18 +65,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-63px">
|
<div class="ml-[63px]">
|
||||||
<div class="my-32px mb-20px text-18px text-[#333333] font-normal flex items-center"><img src="~/assets/images/2.png" alt="" srcset="" class="mr-6px" /> 发布动态</div>
|
<div class="my-[32px] mb-[20px] text-[18px] text-[#333333] font-normal flex items-center"><img src="~/assets/images/2.png" alt="" srcset="" class="mr-[6px]" /> 发布动态</div>
|
||||||
|
|
||||||
<div class="box-border h-470px w-437px border border-[#EEEEEE] rounded-12px border-solid bg-[#FFFFFF] p-15px">
|
<div class="box-border h-[470px] w-[437px] border border-[#EEEEEE] rounded-[12px] border-solid bg-[#FFFFFF] p-[15px]">
|
||||||
<div
|
<div
|
||||||
v-for="item in newDrawList"
|
v-for="item in newDrawList"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
class="flex cursor-pointer items-center justify-between px-10px py-10px text-15px text-[#333333] font-normal hover:bg-[#f5f5f5]"
|
class="flex cursor-pointer items-center justify-between px-[10px] py-[10px] text-[15px] text-[#333333] font-normal hover:bg-[#f5f5f5]"
|
||||||
@click="handleClick(item)"
|
@click="handleClick(item)"
|
||||||
>
|
>
|
||||||
<div class="ellipsis1 w-70%">{{ item.title }}</div>
|
<div class="ellipsis1 w-[70%]">{{ item.title }}</div>
|
||||||
<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>
|
||||||
@ -105,31 +105,36 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 最新动态
|
// 最新动态
|
||||||
const newDrawList = ref<ProjectDrawPageRespVO[]>([])
|
// const newDrawList = ref<ProjectDrawPageRespVO[]>([])
|
||||||
const handlenewDraw = async () => {
|
// const handlenewDraw = async () => {
|
||||||
const res = await newDraw({
|
// const res = await newDraw({
|
||||||
|
// type: 1,
|
||||||
|
// limit: 11,
|
||||||
|
// })
|
||||||
|
// // newDrawList.value = res.data
|
||||||
|
// }
|
||||||
|
// handlenewDraw()
|
||||||
|
|
||||||
|
const [{data: topList},{ data: userTopList}, {data: newDrawList}] = await Promise.all([ userTop({ type: 1 }), userTop({}),newDraw({
|
||||||
type: 1,
|
type: 1,
|
||||||
limit: 11,
|
limit: 11,
|
||||||
})
|
})])
|
||||||
// newDrawList.value = res.data
|
|
||||||
}
|
|
||||||
handlenewDraw()
|
|
||||||
|
|
||||||
const topList = ref<ProjectTrendingScoreUserInfoVO[]>([]) // 最新动态
|
// const topList = ref<ProjectTrendingScoreUserInfoVO[]>([]) // 最新动态
|
||||||
const userTopList = ref<ProjectTrendingScoreUserInfoVO[]>([]) // 最新动态
|
// const userTopList = ref<ProjectTrendingScoreUserInfoVO[]>([]) // 最新动态
|
||||||
const handleuserTop = () => {
|
// const handleuserTop = () => {
|
||||||
Promise.all([userTop({ type: 1 }), userTop({})]).then((res) => {
|
// Promise.all([userTop({ type: 1 }), userTop({})]).then((res) => {
|
||||||
// topList.value = res[0].data
|
// topList.value = res[0].data
|
||||||
// userTopList.value = res[1].data
|
// userTopList.value = res[1].data
|
||||||
|
|
||||||
// console.log('res----',JSON.stringify(res));
|
// console.log('res----',JSON.stringify(res));
|
||||||
|
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
handleuserTop()
|
// handleuserTop()
|
||||||
|
|
||||||
const handleClick = (item: ProjectDrawPageRespVO) => {
|
const handleClick = (item: ProjectDrawPageRespVO) => {
|
||||||
window.open(`/down-drawe-detail?id=${item.id}`, '_blank') // 修改为在新窗口打开
|
navigateTo(`/down-drawe-detail/${item.id}`) // 修改为在新窗口打开
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -31,7 +31,7 @@
|
|||||||
status: 0,
|
status: 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
const { data: bannerList } = useAsyncData('get-setting-Page', async () => {
|
const { data: bannerList } = useAsyncData('get-setting-Page-learning-recommendations', async () => {
|
||||||
const res = await getSettingPage(pageReq)
|
const res = await getSettingPage(pageReq)
|
||||||
return res.data
|
return res.data
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,75 +1,75 @@
|
|||||||
<template>
|
<template>
|
||||||
<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://tuxixi.oss-cn-chengdu.aliyuncs.com/avater.png'"
|
||||||
alt=""
|
alt=""
|
||||||
srcset=""
|
srcset=""
|
||||||
class="h-69px w-69px rd-50%"
|
class="h-[69px] w-[69px] rd-[50%]"
|
||||||
:class="{ 'cursor-pointer': isLogin }"
|
:class="{ 'cursor-pointer': isLogin }"
|
||||||
fit="cover"
|
fit="cover"
|
||||||
@click="handleUserInfo"
|
@click="handleUserInfo"
|
||||||
/>
|
/>
|
||||||
<div class="mt-10px text-16px text-[#333333] font-normal">
|
<div class="mt-[10px] text-[16px] text-[#333333] font-normal flex items-center">
|
||||||
<img v-if="userStore.userInfoRes.vipLevel === 1" src="~/assets/svg/vip.svg" alt="" class="relative top-12px" />
|
|
||||||
<img v-if="userStore.userInfoRes.vipLevel === 2" src="~/assets/svg/svip.svg" alt="" class="relative top-12px" />
|
|
||||||
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 === 2" src="~/assets/svg/svip.svg" alt="" class="relative top-[1px]" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isLogin" class="mt-20px flex flex-col gap-20px px-20px text-14px text-[#333333] font-normal">
|
<div v-if="isLogin" class="mt-[20px] flex flex-col gap-[20px] px-[20px] text-[14px] text-[#333333] font-normal">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<img src="~/assets/images/cad_0 (1).png" alt="" srcset="" />
|
<img src="~/assets/images/cad_0 (1).png" alt="" srcset="" />
|
||||||
<span class="title ml-4px" :title="`${userStaticInfo?.pointCount}`">我的积分: {{ userStaticInfo?.pointCount || 0 }}</span>
|
<span class="title ml-[4px]" :title="`${userStaticInfo?.pointCount}`">我的积分: {{ userStaticInfo?.pointCount || 0 }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<img src="~/assets/images/cad_0 (2).png" alt="" srcset="" />
|
<img src="~/assets/images/cad_0 (2).png" alt="" srcset="" />
|
||||||
<span class="title ml-4px" :title="`${userStaticInfo?.followCount}`">我的收藏: {{ userStaticInfo?.followCount || 0 }}</span>
|
<span class="title ml-[4px]" :title="`${userStaticInfo?.followCount}`">我的收藏: {{ userStaticInfo?.followCount || 0 }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<img src="~/assets/images/cad_0 (3).png" alt="" srcset="" />
|
<img src="~/assets/images/cad_0 (3).png" alt="" srcset="" />
|
||||||
<span class="title ml-4px" :title="`${userStaticInfo?.projectCount}`">我的发布: {{ userStaticInfo?.projectCount || 0 }}</span>
|
<span class="title ml-[4px]" :title="`${userStaticInfo?.projectCount}`">我的发布: {{ userStaticInfo?.projectCount || 0 }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<img src="~/assets/images/cad_0 (4).png" alt="" srcset="" />
|
<img src="~/assets/images/cad_0 (4).png" alt="" srcset="" />
|
||||||
<span class="title ml-4px" :title="`${userStaticInfo?.downloadCount}`">我的下载: {{ userStaticInfo?.downloadCount || 0 }}</span>
|
<span class="title ml-[4px]" :title="`${userStaticInfo?.downloadCount}`">我的下载: {{ userStaticInfo?.downloadCount || 0 }}</span>
|
||||||
</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"
|
||||||
>立即登录</div
|
>立即登录</div
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="h-37px w-101px cursor-pointer border border-[#DDDDDD] rounded-2px border-solid text-center text-14px text-[#333333] font-normal line-height-37px"
|
class="h-[37px] w-[101px] cursor-pointer border border-[#DDDDDD] rounded-[2px] border-solid text-center text-[14px] text-[#333333] font-normal line-height-[37px]"
|
||||||
@click="handleRegister"
|
@click="handleRegister"
|
||||||
>免费注册</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"
|
||||||
>发布图纸</div
|
>发布图纸</div
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="h-37px w-101px cursor-pointer border border-[#DDDDDD] rounded-2px border-solid text-center text-14px text-[#333333] font-normal line-height-37px"
|
class="h-[37px] w-[101px] cursor-pointer border border-[#DDDDDD] rounded-[2px] border-solid text-center text-[14px] text-[#333333] font-normal line-height-[37px]"
|
||||||
@click="handleLoginOut"
|
@click="handleLoginOut"
|
||||||
>退出登录</div
|
>退出登录</div
|
||||||
>
|
>
|
||||||
</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="handleLoginWechat" />
|
||||||
<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>
|
||||||
|
|
||||||
<div class="sign-bonus mt-18px" @click="handleSign">
|
<div class="sign-bonus mt-[18px] cursor-pointer" @click="handleSign">
|
||||||
<img src="~/assets/images/sign.png" alt="签到奖励" class="bonus-image" />
|
<img src="~/assets/images/sign.png" alt="签到奖励" class="bonus-image" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -81,9 +81,9 @@
|
|||||||
import { handleLoginQQ, handleLoginWechat } from '~/utils/login'
|
import { handleLoginQQ, handleLoginWechat } from '~/utils/login'
|
||||||
import type { UserStatisticsCountRespVO } from '~/api/personal-center/types'
|
import type { UserStatisticsCountRespVO } from '~/api/personal-center/types'
|
||||||
import { getUserStatistics } from '~/api/personal-center/index'
|
import { getUserStatistics } from '~/api/personal-center/index'
|
||||||
import useUserStore from '~/store/user'
|
import useUserStore from '~/stores/user'
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const instance = getCurrentInstance()
|
const app = useNuxtApp()
|
||||||
|
|
||||||
// 是否登录
|
// 是否登录
|
||||||
const isLogin = computed(() => {
|
const isLogin = computed(() => {
|
||||||
@ -102,27 +102,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleLogin = () => {
|
const handleLogin = () => {
|
||||||
if (instance) {
|
app.$openLogin()
|
||||||
// instance.appContext.config.globalProperties.$openLogin()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleRegister = () => {
|
const handleRegister = () => {
|
||||||
if (instance) {
|
app.$openRegister()
|
||||||
// instance.appContext.config.globalProperties.$openRegister()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleLoginPhone = () => {
|
const handleLoginPhone = () => {
|
||||||
if (instance) {
|
app.$openLogin('verify')
|
||||||
// instance.appContext.config.globalProperties.$openLogin('verify')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleLoginEmail = () => {
|
const handleLoginEmail = () => {
|
||||||
if (instance) {
|
app.$openLoginEmail()
|
||||||
// instance.appContext.config.globalProperties.$openLoginEmail()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleUserInfo = () => {
|
const handleUserInfo = () => {
|
||||||
@ -132,7 +124,7 @@
|
|||||||
|
|
||||||
// 发布图纸
|
// 发布图纸
|
||||||
const handleDrawe = () => {
|
const handleDrawe = () => {
|
||||||
navigateTo('/upnew/drawe') // 修改为在新窗口打开
|
navigateTo('/upnew') // 修改为在新窗口打开
|
||||||
}
|
}
|
||||||
|
|
||||||
// 推出登录
|
// 推出登录
|
||||||
@ -145,11 +137,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleSign = () => {
|
const handleSign = () => {
|
||||||
navigateTo('/sign-page') // 修改为在新窗口打开
|
navigateTo('/sign-content') // 修改为在新窗口打开
|
||||||
}
|
}
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
if (isLogin.value) {
|
if (isLogin.value && import.meta.client) {
|
||||||
fetchUserStatistics()
|
fetchUserStatistics()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -20,55 +20,40 @@
|
|||||||
<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
|
<img src="~/assets/images/voice.png" alt="" srcset="" class="mr-10px h-15px w-16px" />
|
||||||
src="~/assets/images/voice.png"
|
<Vue3Marquee :duration="10" direction="normal" pause-on-hover>
|
||||||
alt=""
|
· 经典来袭,SolidWorks装配经典案例之气动发动机
|
||||||
srcset=""
|
|
||||||
class="mr-10px h-15px w-16px"
|
|
||||||
/>
|
|
||||||
<Vue3Marquee :duration="10" direction="normal" pause-on-hover
|
|
||||||
>· 经典来袭,SolidWorks装配经典案例之气动发动机
|
|
||||||
</Vue3Marquee>
|
</Vue3Marquee>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref } from "vue";
|
import { reactive, ref } from 'vue'
|
||||||
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 } from '~/api/home/index'
|
||||||
import type { PageResultIndexSettingRespVO } from "~/api/home/type";
|
|
||||||
|
|
||||||
const pageReq = reactive({
|
const pageReq = reactive({
|
||||||
type: 1,
|
type: 1,
|
||||||
status: 0,
|
status: 0,
|
||||||
});
|
})
|
||||||
|
|
||||||
const { data: bannerList } = useAsyncData("get-setting-Page", async () => {
|
const { data: bannerList } = useAsyncData('get-setting-Page-main-content', async () => {
|
||||||
const res = await getSettingPage(pageReq);
|
const res = await getSettingPage(pageReq)
|
||||||
return res.data;
|
return res.data
|
||||||
});
|
})
|
||||||
|
|
||||||
// const bannerList = ref<PageResultIndexSettingRespVO[]>([])
|
const handleClick = (url: string) => {
|
||||||
// const getBanner = async () => {
|
|
||||||
// const res = await getSettingPage(pageReq)
|
|
||||||
// if (res.code === 0) {
|
|
||||||
// bannerList.value = res.data
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// getBanner()
|
|
||||||
|
|
||||||
const handleClick = (url: string) => {
|
|
||||||
if (url) {
|
if (url) {
|
||||||
navigateTo(url);
|
navigateTo(url)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.main-content {
|
.main-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mt-34px w-100%">
|
<div class="mt-[34px] w-[100%]">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<KlTabBar v-model="query.type" :data="tabBar" :show-icon="true" />
|
<KlTabBar v-model="query.type" :data="tabBar" :show-icon="true" />
|
||||||
<div class="flex gap-15px">
|
<div class="flex gap-[15px]">
|
||||||
<span
|
<span
|
||||||
v-for="(item, index) in projectTypeList"
|
v-for="(item, index) in projectTypeList"
|
||||||
:key="index"
|
:key="index"
|
||||||
:class="{ 'color-#1A65FF! border-b-2px border-b-solid border-b-[#1A65FF] rounded-1px pb-3px': query.projectTypeDay === item.id }"
|
:class="{ 'color-[#1A65FF!] border-b-[2px] border-b-solid border-b-[#1A65FF] rounded-[1px] pb-[3px]': query.projectTypeDay === item.id }"
|
||||||
class="cursor-pointer text-14px color-#333333"
|
class="cursor-pointer text-[14px] color-[#333333]"
|
||||||
@mouseenter="handleHover(item)"
|
@mouseenter="handleHover(item)"
|
||||||
@click="handleClickType(item)"
|
@click="handleClickType(item)"
|
||||||
>
|
>
|
||||||
@ -15,7 +15,7 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content mt-10px flex">
|
<div class="content mt-[10px] flex">
|
||||||
<!-- <div class="sider">
|
<!-- <div class="sider">
|
||||||
<div class="box-border h-100% h-55px w-221px flex items-center rounded-lg bg-[#1A65FF] pl-24px text-white">
|
<div class="box-border h-100% h-55px w-221px flex items-center rounded-lg bg-[#1A65FF] pl-24px text-white">
|
||||||
<img src="~/assets/images/1.png" alt="" srcset="" />
|
<img src="~/assets/images/1.png" alt="" srcset="" />
|
||||||
@ -40,23 +40,23 @@
|
|||||||
<el-empty v-if="projectTypeList.length === 0" description="暂无数据"></el-empty>
|
<el-empty v-if="projectTypeList.length === 0" description="暂无数据"></el-empty>
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div> -->
|
||||||
<div class="box-border w-100%">
|
<div class="box-border w-[100%]">
|
||||||
<div class="grid grid-cols-5 gap-17px">
|
<div class="grid grid-cols-5 gap-[17px]">
|
||||||
<div
|
<div
|
||||||
v-for="item in hotTopList"
|
v-for="item in hotTopList"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
class="cursor-pointer border border-[#EEEEEE] rounded-1px border-solid bg-[#FFFFFF]"
|
class="cursor-pointer border border-[#EEEEEE] rounded-[1px] border-solid bg-[#FFFFFF]"
|
||||||
@click="handleCardClick(item)"
|
@click="handleCardClick(item)"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div class="h-212px w-100%">
|
<div class="h-[212px] w-[100%]">
|
||||||
<el-image :src="item.iconUrl" alt="" srcset="" fit="cover" class="block h-100% w-100%" />
|
<el-image :src="item.iconUrl" alt="" srcset="" fit="cover" class="block h-[100%] w-[100%]" />
|
||||||
</div>
|
</div>
|
||||||
<div class="ellipsis mx-20px my-11px text-14px color-#333333 font-normal">{{ item.title }}</div>
|
<div class="ellipsis mx-[20px] my-[11px] text-[14px] color-[#333333] font-normal">{{ item.title }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-empty v-if="hotTopList.length === 0" description="暂无数据"></el-empty>
|
<el-empty v-if="hotTopList?.length === 0" description="暂无数据"></el-empty>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="morefont-400 text-16px text-[#1A65FF] text-right cursor-pointer"> 查看更多 >> </div> -->
|
<!-- <div class="morefont-400 text-16px text-[#1A65FF] text-right cursor-pointer"> 查看更多 >> </div> -->
|
||||||
@ -70,6 +70,11 @@
|
|||||||
import { hotTop, hotTag } from '~/api/home/index'
|
import { hotTop, hotTag } from '~/api/home/index'
|
||||||
import type { ProjectDrawPageRespVO, ProjectDictNodeVO } from '~/api/home/type'
|
import type { ProjectDrawPageRespVO, ProjectDictNodeVO } from '~/api/home/type'
|
||||||
|
|
||||||
|
/** tianjia key 接口刷新了 页面没变化 */
|
||||||
|
definePageMeta({
|
||||||
|
key: 'PopularDrawings', // 页面的唯一标识,用于区分不同的页面
|
||||||
|
})
|
||||||
|
|
||||||
/** 请求参数 */
|
/** 请求参数 */
|
||||||
const query = reactive({
|
const query = reactive({
|
||||||
type: 1,
|
type: 1,
|
||||||
@ -105,7 +110,7 @@
|
|||||||
/** 点击卡片 */
|
/** 点击卡片 */
|
||||||
const handleCardClick = (item: ProjectDrawPageRespVO) => {
|
const handleCardClick = (item: ProjectDrawPageRespVO) => {
|
||||||
// 跳转到下载详情页 并且是单独开标签
|
// 跳转到下载详情页 并且是单独开标签
|
||||||
navigateTo(`/down-drawe-detail?id=${item.id}`) // 修改为在新窗口打开
|
navigateTo(`/down-drawe-detail/${item.id}`) // 修改为在新窗口打开
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleClickType = (primary?: ProjectDictNodeVO, secondary?: ProjectDictNodeVO) => {
|
const handleClickType = (primary?: ProjectDictNodeVO, secondary?: ProjectDictNodeVO) => {
|
||||||
@ -127,48 +132,83 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 热门数据 */
|
/** 热门数据 */
|
||||||
const hotTopList = ref<ProjectDrawPageRespVO[]>([])
|
// const hotTopList = ref<ProjectDrawPageRespVO[]>([])
|
||||||
const getHotTop = () => {
|
// const getHotTop = () => {
|
||||||
hotTop({
|
// hotTop({
|
||||||
type: query.type,
|
// type: query.type,
|
||||||
projectType: query.projectTypeDay,
|
// projectType: query.projectTypeDay,
|
||||||
isDomestic: query.isDomestic,
|
// isDomestic: query.isDomestic,
|
||||||
projectTypeTop: query.projectTypeDay,
|
// projectTypeTop: query.projectTypeDay,
|
||||||
}).then((res) => {
|
// }).then((res) => {
|
||||||
if (res.code === 0) {
|
// if (res.code === 0) {
|
||||||
hotTopList.value = res.data || []
|
// hotTopList.value = res.data || []
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
/** 获取分类下拉框 */
|
const { data: projectTypeList, refresh: getParent } = await useAsyncData('projectTypeListChildren-PopularDrawings-popularDrawings', async () => {
|
||||||
const projectTypeList = ref<ProjectDictNodeVO[]>([])
|
const res = await hotTag({
|
||||||
const projectTypeListChildren = ref<ProjectDictNodeVO[]>([])
|
|
||||||
const getParent = () => {
|
|
||||||
hotTag({
|
|
||||||
type: query.type,
|
type: query.type,
|
||||||
limit: 6,
|
limit: 6,
|
||||||
size: 1000,
|
size: 1000,
|
||||||
}).then((res) => {
|
|
||||||
if (res.code === 0) {
|
|
||||||
if (Array.isArray(res.data) && res.data.length > 0) {
|
|
||||||
projectTypeList.value = [...res.data, { id: '0', name: '全部分类', children: [] }]
|
|
||||||
projectTypeListChildren.value = res.data[0].children || []
|
|
||||||
query.projectTypeDay = res.data[0].id || ''
|
|
||||||
query.projectType = res.data[0]!.children?.[0]!.id || ''
|
|
||||||
// 热门数据
|
|
||||||
getHotTop()
|
|
||||||
} else {
|
|
||||||
hotTopList.value = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
const all = [{ id: '0', name: '全部分类', children: [] }]
|
||||||
|
if (Array.isArray(res.data) && res.data?.length > 0) {
|
||||||
|
const total = [...res.data, ...all]
|
||||||
|
// query.projectTypeDay = total[0]?.id || ''
|
||||||
|
// query.projectType = total[0]!.children?.[0]?.id || ''
|
||||||
|
return total
|
||||||
}
|
}
|
||||||
|
return []
|
||||||
|
})
|
||||||
|
|
||||||
|
// if (!projectTypeList.value?.length) {
|
||||||
|
// throw createError({
|
||||||
|
// statusCode: 404,
|
||||||
|
// statusMessage: 'Page Not Found',
|
||||||
|
// fatal: true,
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
const { data: hotTopList, refresh: getHotTop } = useAsyncData('hotTop-PopularDrawings-popularDrawings', async () => {
|
||||||
|
const res = await hotTop({
|
||||||
|
type: query.type,
|
||||||
|
// @ts-ignore
|
||||||
|
projectType: query.projectTypeDay || projectTypeList.value[0].id,
|
||||||
|
isDomestic: query.isDomestic || 1,
|
||||||
|
projectTypeTop: query.projectTypeDay || projectTypeList.value?.[0].id,
|
||||||
|
})
|
||||||
|
return res.data || []
|
||||||
|
})
|
||||||
|
|
||||||
|
/** 获取分类下拉框 */
|
||||||
|
// const projectTypeList = ref<ProjectDictNodeVO[]>([])
|
||||||
|
// // const projectTypeListChildren = ref<ProjectDictNodeVO[]>([])
|
||||||
|
// const getParent = () => {
|
||||||
|
// hotTag({
|
||||||
|
// type: query.type,
|
||||||
|
// limit: 6,
|
||||||
|
// size: 1000,
|
||||||
|
// }).then((res) => {
|
||||||
|
// if (res.code === 0) {
|
||||||
|
// if (Array.isArray(res.data) && res.data.length > 0) {
|
||||||
|
// projectTypeList.value = [...res.data, { id: '0', name: '全部分类', children: [] }]
|
||||||
|
// projectTypeListChildren.value = res.data[0].children || []
|
||||||
|
// query.projectTypeDay = res.data[0].id || ''
|
||||||
|
// query.projectType = res.data[0]!.children?.[0]!.id || ''
|
||||||
|
// // 热门数据
|
||||||
|
// getHotTop()
|
||||||
|
// } else {
|
||||||
|
// hotTopList.value = []
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
const handleHover = (item: ProjectDictNodeVO) => {
|
const handleHover = (item: ProjectDictNodeVO) => {
|
||||||
query.projectTypeDay = item.id || ''
|
query.projectTypeDay = item.id || ''
|
||||||
if (item.name === '全部分类') return
|
if (item.name === '全部分类') return
|
||||||
projectTypeListChildren.value = item.children || []
|
// projectTypeListChildren.value = item.children || []
|
||||||
query.projectType = item.children?.[0].id || ''
|
query.projectType = item.children?.[0].id || ''
|
||||||
// 热门数据
|
// 热门数据
|
||||||
getHotTop()
|
getHotTop()
|
||||||
@ -182,11 +222,12 @@
|
|||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => query.type,
|
() => query.type,
|
||||||
() => {
|
async () => {
|
||||||
getParent()
|
await getParent()
|
||||||
|
await getHotTop()
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
immediate: true,
|
// immediate: true,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -54,8 +54,8 @@
|
|||||||
// })
|
// })
|
||||||
// }
|
// }
|
||||||
|
|
||||||
const { data: recommendTopList, refresh: getRecommendTop} = useAsyncData('recommendTop', async () => {
|
const { data: recommendTopList, refresh: getRecommendTop} = useAsyncData('recommendTop-RecommendedColumns', async () => {
|
||||||
// @ts-ignore
|
|
||||||
const res = await recommendTop(query)
|
const res = await recommendTop(query)
|
||||||
return res.data || []
|
return res.data || []
|
||||||
})
|
})
|
||||||
|
|||||||
@ -11,30 +11,16 @@
|
|||||||
<!-- @click="handleSubmenuClick(item)" -->
|
<!-- @click="handleSubmenuClick(item)" -->
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
<!-- 悬浮浮窗 -->
|
<!-- 悬浮浮窗 -->
|
||||||
<div
|
<div v-if="activeIndex === index" class="submenu-panel" :style="{ top: submenuTop + 'px' }" @mouseenter="keepSubmenuVisible" @mouseleave="hideSubMenu">
|
||||||
v-if="activeIndex === index"
|
|
||||||
class="submenu-panel"
|
|
||||||
:style="{ top: submenuTop + 'px' }"
|
|
||||||
@mouseenter="keepSubmenuVisible"
|
|
||||||
@mouseleave="hideSubMenu"
|
|
||||||
>
|
|
||||||
<div class="submenu-content">
|
<div class="submenu-content">
|
||||||
<!-- <div class="text-right">更多</div> -->
|
<!-- <div class="text-right">更多</div> -->
|
||||||
<div class="submenu-group">
|
<div class="submenu-group">
|
||||||
<template v-for="group in item.children" :key="group.id">
|
<template v-for="group in item.children" :key="group.id">
|
||||||
<div
|
<div class="submenu-group-title" @click.stop="handleSubmenuClick(group)">
|
||||||
class="submenu-group-title"
|
|
||||||
@click.stop="handleSubmenuClick(group)"
|
|
||||||
>
|
|
||||||
{{ group.name }}
|
{{ group.name }}
|
||||||
</div>
|
</div>
|
||||||
<div class="submenu-group-items">
|
<div class="submenu-group-items">
|
||||||
<div
|
<div v-for="sub in group.children" :key="sub.id" class="submenu-item" @click.stop="handleSubmenuClick(sub)">
|
||||||
v-for="sub in group.children"
|
|
||||||
:key="sub.id"
|
|
||||||
class="submenu-item"
|
|
||||||
@click.stop="handleSubmenuClick(group, sub)"
|
|
||||||
>
|
|
||||||
{{ sub.name }}
|
{{ sub.name }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -47,107 +33,99 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted } from "vue";
|
import { ref, onMounted } from 'vue'
|
||||||
import type { ComponentPublicInstance } from "vue";
|
import type { ComponentPublicInstance } from 'vue'
|
||||||
import { tab2 } from "~/api/home/index";
|
import { tab2 } from '~/api/home/index'
|
||||||
import type { ProjectDictNodeVO } from "~/api/home/type";
|
import type { ProjectDictNodeVO } from '~/api/home/type'
|
||||||
|
|
||||||
const activeIndex = ref(-1);
|
const activeIndex = ref(-1)
|
||||||
const submenuTop = ref(0);
|
const submenuTop = ref(0)
|
||||||
// const submenuLeft = ref(0)
|
// const submenuLeft = ref(0)
|
||||||
const sideMenu = ref();
|
const sideMenu = ref()
|
||||||
const menuItemRefs = ref<HTMLElement[]>([]);
|
const menuItemRefs = ref<HTMLElement[]>([])
|
||||||
|
|
||||||
// const menuItems = ref<ProjectDictNodeVO[]>([]);
|
// const menuItems = ref<ProjectDictNodeVO[]>([]);
|
||||||
|
|
||||||
// 等待数据加载完成再进行渲染 :courseData 对data进行别名赋值
|
// 等待数据加载完成再进行渲染 :courseData 对data进行别名赋值
|
||||||
const { data: menuItems, pending, error } = useAsyncData(
|
const {
|
||||||
'tab2-list',
|
data: menuItems,
|
||||||
async () => {
|
pending,
|
||||||
|
error,
|
||||||
|
} = useAsyncData('tab2-list', async () => {
|
||||||
const res = await tab2()
|
const res = await tab2()
|
||||||
const arr = [];
|
const arr = []
|
||||||
for (let i = 0; i < res.data?.length; i += 2) {
|
for (let i = 0; i < res.data?.length; i += 2) {
|
||||||
arr.push({
|
arr.push({
|
||||||
children: res.data.slice(i, i + 2),
|
children: res.data.slice(i, i + 2),
|
||||||
name: getName(res.data.slice(i, i + 2)),
|
name: getName(res.data.slice(i, i + 2)),
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
return arr
|
return arr
|
||||||
}
|
})
|
||||||
)
|
|
||||||
|
|
||||||
|
const showSubMenu = (index: number) => {
|
||||||
|
|
||||||
|
|
||||||
const showSubMenu = (index: number) => {
|
|
||||||
// if (menuItems.value.length === index + 1) {
|
// if (menuItems.value.length === index + 1) {
|
||||||
// return
|
// 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)
|
||||||
// submenuTop.value = window.scrollY
|
// submenuTop.value = window.scrollY
|
||||||
};
|
|
||||||
|
|
||||||
const hideSubMenu = () => {
|
|
||||||
activeIndex.value = -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSubmenuClick = (
|
|
||||||
primary?: ProjectDictNodeVO,
|
|
||||||
secondary?: ProjectDictNodeVO,
|
|
||||||
tertiary?: 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)}`);
|
const hideSubMenu = () => {
|
||||||
};
|
activeIndex.value = -1
|
||||||
|
}
|
||||||
|
|
||||||
const keepSubmenuVisible = () => {
|
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`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const keepSubmenuVisible = () => {
|
||||||
// activeIndex.value = activeIndex.value // 保持当前索引
|
// activeIndex.value = activeIndex.value // 保持当前索引
|
||||||
};
|
|
||||||
|
|
||||||
const setMenuItemRef = (
|
|
||||||
el: Element | ComponentPublicInstance | null,
|
|
||||||
index: number
|
|
||||||
) => {
|
|
||||||
if (el && "offsetTop" in el) {
|
|
||||||
menuItemRefs.value[index] = el as HTMLElement;
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const getName = (arr: any[]) => {
|
const setMenuItemRef = (el: Element | ComponentPublicInstance | null, index: number) => {
|
||||||
|
if (el && 'offsetTop' in el) {
|
||||||
|
menuItemRefs.value[index] = el as HTMLElement
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getName = (arr: any[]) => {
|
||||||
if (arr.length === 1) {
|
if (arr.length === 1) {
|
||||||
return arr[0].name;
|
return arr[0].name
|
||||||
} else {
|
} else {
|
||||||
return arr[0].name + " / " + arr[1].name;
|
return arr[0].name + ' / ' + arr[1].name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const init = () => {
|
const init = () => {
|
||||||
// 获取标签
|
// 获取标签
|
||||||
// getLabel()
|
// getLabel()
|
||||||
};
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// init();
|
// init();
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.side-menu {
|
.side-menu {
|
||||||
width: 221px;
|
width: 221px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
/* padding: 10px 0; */
|
/* padding: 10px 0; */
|
||||||
@ -161,20 +139,20 @@ onMounted(() => {
|
|||||||
-ms-overflow-style: none; /* IE and Edge */
|
-ms-overflow-style: none; /* IE and Edge */
|
||||||
z-index: 9;
|
z-index: 9;
|
||||||
/* padding-top: 10px; */
|
/* padding-top: 10px; */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 隐藏 Webkit 浏览器的滚动条 */
|
/* 隐藏 Webkit 浏览器的滚动条 */
|
||||||
.side-menu::-webkit-scrollbar {
|
.side-menu::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 鼠标悬停时显示滚动条 */
|
/* 鼠标悬停时显示滚动条 */
|
||||||
.side-menu:hover {
|
.side-menu:hover {
|
||||||
scrollbar-width: none; /* Firefox */
|
scrollbar-width: none; /* Firefox */
|
||||||
-ms-overflow-style: none; /* IE and Edge */
|
-ms-overflow-style: none; /* IE and Edge */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .side-menu:hover::-webkit-scrollbar {
|
/* .side-menu:hover::-webkit-scrollbar {
|
||||||
display: block;
|
display: block;
|
||||||
width: 8px !important;
|
width: 8px !important;
|
||||||
}
|
}
|
||||||
@ -188,26 +166,26 @@ onMounted(() => {
|
|||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
} */
|
} */
|
||||||
|
|
||||||
.menu-item {
|
.menu-item {
|
||||||
/* position: relative; */
|
/* position: relative; */
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 4px 24px;
|
padding: 10px 24px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
/* transition: all 0.3s ease; */
|
/* transition: all 0.3s ease; */
|
||||||
color: #333;
|
color: #333;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
z-index: 9;
|
z-index: 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-item:hover {
|
.menu-item:hover {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
color: #1890ff;
|
color: #1890ff;
|
||||||
border: 1px solid #1890ff;
|
border: 1px solid #1890ff;
|
||||||
border-right: transparent !important;
|
border-right: transparent !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.submenu-panel {
|
.submenu-panel {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 220px;
|
left: 220px;
|
||||||
top: 0;
|
top: 0;
|
||||||
@ -222,9 +200,9 @@ onMounted(() => {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
min-height: 480px;
|
min-height: 480px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.submenu-panel::before {
|
.submenu-panel::before {
|
||||||
/* content: '';
|
/* content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -6px;
|
left: -6px;
|
||||||
@ -236,9 +214,9 @@ onMounted(() => {
|
|||||||
border-bottom: 8px solid transparent;
|
border-bottom: 8px solid transparent;
|
||||||
border-right: 8px solid #fff;
|
border-right: 8px solid #fff;
|
||||||
filter: drop-shadow(-2px 0 2px rgba(0, 0, 0, 0.1)); */
|
filter: drop-shadow(-2px 0 2px rgba(0, 0, 0, 0.1)); */
|
||||||
}
|
}
|
||||||
|
|
||||||
.submenu-content {
|
.submenu-content {
|
||||||
/* flex: 1; */
|
/* flex: 1; */
|
||||||
/* display: grid; */
|
/* display: grid; */
|
||||||
/* grid-template-columns: repeat(3, 1fr); */
|
/* grid-template-columns: repeat(3, 1fr); */
|
||||||
@ -279,18 +257,18 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.submenu-item {
|
.submenu-item {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
display: inline-block; /* 改为行内块元素 */
|
display: inline-block; /* 改为行内块元素 */
|
||||||
/* padding: 8px 12px; */
|
/* padding: 8px 12px; */
|
||||||
padding-right: 12px;
|
padding-right: 12px;
|
||||||
/* padding-bottom: 8px; */
|
/* padding-bottom: 8px; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.submenu-item:hover {
|
.submenu-item:hover {
|
||||||
color: #1890ff;
|
color: #1890ff;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -21,8 +21,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import KlSearch from '~/layout/kl-search/index.vue'
|
import KlSearch from '~/components/kl-search/index.vue'
|
||||||
import KlMenuV2 from '~/layout/kl-menus-v2/index.vue'
|
import KlMenuV2 from '~/components/kl-menus-v2/index.vue'
|
||||||
import SideMenu from '~/pages/home/components/SideMenu.vue'
|
import SideMenu from '~/pages/home/components/SideMenu.vue'
|
||||||
import MainContent from '~/pages/home/components/MainContent.vue'
|
import MainContent from '~/pages/home/components/MainContent.vue'
|
||||||
import RecommendedColumns from '~/pages/home/components/RecommendedColumns.vue'
|
import RecommendedColumns from '~/pages/home/components/RecommendedColumns.vue'
|
||||||
|
|||||||
11
pages/m/index.vue
Normal file
11
pages/m/index.vue
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1>Mobile Page</h1>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// Mobile specific logic can be added here
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
@ -0,0 +1,126 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 导航 -->
|
||||||
|
<SeoHead title="工程设计模型下载_CAD设计图纸资源库" />
|
||||||
|
<KlNavTab active="模型" :type="3" />
|
||||||
|
<div class="ma-auto w-[1440px]">
|
||||||
|
<!-- 图纸分类 -->
|
||||||
|
<KlWallpaperCategory v-model="query" v-model:level="level" :type="3" />
|
||||||
|
<!-- 推荐栏目 -->
|
||||||
|
<RecommendedColumnsV2 v-model="query" v-model:result="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="[12, 24, 48]"
|
||||||
|
:total="result?.total"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
@size-change="handleClickSize"
|
||||||
|
@current-change="handeClickCurrent"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import KlNavTab from '~/components/kl-nav-tab/index.vue'
|
||||||
|
import KlWallpaperCategory from '~/components/kl-wallpaper-category/index.vue'
|
||||||
|
import RecommendedColumnsV2 from '~/components/model-components/RecommendedColumnsV2.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: 3,
|
||||||
|
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 handleClickSize = (val: number) => {
|
||||||
|
query.value.pageSize = val
|
||||||
|
// getPage()
|
||||||
|
navigateTo(`/model/${query.value.projectType}/${query.value.pageNo}/${val}/${query.value.editions}/${query.value.source}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handeClickCurrent = (val: number) => {
|
||||||
|
query.value.pageNo = val
|
||||||
|
// getPage()
|
||||||
|
navigateTo(`/model/${query.value.projectType}/${val}/${query.value.pageSize}/${query.value.editions}/${query.value.source}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data: result, refresh: getPage } = useAsyncData(
|
||||||
|
`draw-page-list-${query.value.projectType}-${query.value.editions}-${query.value.source}-${query.value.pageNo}-${query.value.pageSize}`,
|
||||||
|
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(`/model/${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>
|
||||||
@ -1,7 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- 导航 -->
|
<!-- 导航 -->
|
||||||
|
<SeoHead title="工程设计模型下载_CAD设计图纸资源库" />
|
||||||
<KlNavTab active="模型" :type="3" />
|
<KlNavTab active="模型" :type="3" />
|
||||||
<div class="ma-auto w-1440px">
|
<div class="ma-auto w-[1440px]">
|
||||||
<!-- 图纸分类 -->
|
<!-- 图纸分类 -->
|
||||||
<KlWallpaperCategory v-model="query" v-model:level="level" :type="3" />
|
<KlWallpaperCategory v-model="query" v-model:level="level" :type="3" />
|
||||||
<!-- 推荐栏目 -->
|
<!-- 推荐栏目 -->
|
||||||
@ -9,12 +10,12 @@
|
|||||||
<!-- 精选专题 -->
|
<!-- 精选专题 -->
|
||||||
<!-- <FeaturedSpecials></FeaturedSpecials> -->
|
<!-- <FeaturedSpecials></FeaturedSpecials> -->
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<div class="mt-10px flex justify-center">
|
<div class="mt-[10px] flex justify-center">
|
||||||
<el-pagination
|
<el-pagination
|
||||||
v-model:current-page="query.pageNo"
|
v-model:current-page="query.pageNo"
|
||||||
v-model:page-size="query.pageSize"
|
v-model:page-size="query.pageSize"
|
||||||
:page-sizes="[12, 24, 48]"
|
:page-sizes="[12, 24, 48]"
|
||||||
:total="result.total"
|
:total="result?.total"
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
@size-change="handleChangeSize"
|
@size-change="handleChangeSize"
|
||||||
@current-change="handleChangeCurrent"
|
@current-change="handleChangeCurrent"
|
||||||
@ -25,7 +26,7 @@
|
|||||||
<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 KlWallpaperCategory from '~/components/kl-wallpaper-category/index.vue'
|
import KlWallpaperCategory from '~/components/kl-wallpaper-category/index.vue'
|
||||||
import RecommendedColumnsV2 from './components/RecommendedColumnsV2.vue'
|
import RecommendedColumnsV2 from '~/components/model-components/RecommendedColumnsV2.vue'
|
||||||
// import FeaturedSpecials from './components/FeaturedSpecials.vue'
|
// import FeaturedSpecials from './components/FeaturedSpecials.vue'
|
||||||
|
|
||||||
import { reactive, watch, ref } from 'vue'
|
import { reactive, watch, ref } from 'vue'
|
||||||
@ -38,57 +39,76 @@
|
|||||||
? JSON.parse(route.query.level as string)
|
? JSON.parse(route.query.level as string)
|
||||||
: [
|
: [
|
||||||
{
|
{
|
||||||
id: '0',
|
id: -1,
|
||||||
name: '模型库',
|
name: '模型库',
|
||||||
isChildren: false,
|
isChildren: false,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
const query = reactive<pageReq>({
|
const query = ref<pageReq>({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 12,
|
pageSize: 12,
|
||||||
projectType: '',
|
projectType: '-1',
|
||||||
editions: '',
|
editions: '-1',
|
||||||
source: '',
|
source: -1,
|
||||||
type: 3,
|
type: 3,
|
||||||
})
|
})
|
||||||
const result = reactive<pageRes>({
|
// const result = reactive<pageRes>({
|
||||||
list: [],
|
// list: [],
|
||||||
total: 0,
|
// total: 0,
|
||||||
})
|
// })
|
||||||
|
|
||||||
// 如果id存在,则设置projectType
|
// 如果id存在,则设置projectType
|
||||||
if (level.value.length) {
|
if (level.value.length) {
|
||||||
query.projectType = level.value[level.value.length - 1].id || ''
|
// query.projectType = level.value[level.value.length - 1].id || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const getPage = () => {
|
const { data: result } = useAsyncData(
|
||||||
page(query).then((res) => {
|
`draw-page-list-${query.value.projectType}-${query.value.editions}-${query.value.source}-${query.value.pageNo}-${query.value.pageSize}`,
|
||||||
const { data, code } = res
|
async () => {
|
||||||
if (code === 0) {
|
const res = await page({
|
||||||
result.list = data.list
|
...query.value,
|
||||||
result.total = data.total
|
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,
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
getPage()
|
// const getPage = () => {
|
||||||
|
// page(query).then((res) => {
|
||||||
|
// const { data, code } = res
|
||||||
|
// if (code === 0) {
|
||||||
|
// result.list = data.list
|
||||||
|
// result.total = data.total
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
const handleChangeSize = (size: number) => {
|
// getPage()
|
||||||
query.pageSize = size
|
|
||||||
query.pageNo = 1
|
const handleChangeSize = (val: number) => {
|
||||||
getPage()
|
query.value.pageSize = val
|
||||||
|
// query.pageNo = 1
|
||||||
|
// getPage()
|
||||||
|
navigateTo(`/model/${query.value.projectType}/${query.value.pageNo}/${val}/${query.value.editions}/${query.value.source}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleChangeCurrent = (current: number) => {
|
const handleChangeCurrent = (current: number) => {
|
||||||
query.pageNo = current
|
query.value.pageNo = current
|
||||||
getPage()
|
// getPage()
|
||||||
|
navigateTo(`/model/${query.value.projectType}/${current}/${query.value.pageSize}/${query.value.editions}/${query.value.source}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
watch([() => query.projectType, () => query.editions, () => query.source], (val) => {
|
watch([() => query.value.projectType, () => query.value.editions, () => query.value.source], (val) => {
|
||||||
if (val) {
|
if (val) {
|
||||||
getPage()
|
// getPage()
|
||||||
|
navigateTo(`/model/${query.value.projectType}/1/${query.value.pageSize}/${query.value.editions}/${query.value.source}`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,70 +1,72 @@
|
|||||||
<template>
|
<template>
|
||||||
<KlNavTab />
|
<KlNavTab />
|
||||||
<div class="ma-auto w-1198px flex justify-between">
|
<div class="ma-auto w-[1198px] flex justify-between">
|
||||||
<div class="left mt-25px box-border h-370px w-260px border border-[#EEEEEE] rounded-4px border-solid bg-[#FFFFFF] text-15px text-[#333333] font-medium">
|
<div
|
||||||
<nuxt-link to="/personal/center/info" class="flex items-center justify-between py-14px">
|
class="left mt-[25px] box-border h-[370px] w-[260px] border border-[#EEEEEE] rounded-[4px] border-solid bg-[#FFFFFF] text-[15px] text-[#333333] font-medium"
|
||||||
<div class="flex items-center pl-20px">
|
>
|
||||||
<img v-if="route.path.startsWith('/personal/center/info')" src="~/assets/images/user3.png" alt="" srcset="" class="h-20px" />
|
<nuxt-link to="/personal-Center/info" class="flex items-center justify-between py-[14px]">
|
||||||
<img v-else src="~/assets/images/个人.png" alt="" srcset="" class="h-20px" />
|
<div class="flex items-center pl-[20px]">
|
||||||
<span class="ml-10px">个人中心</span>
|
<img v-if="route.path.startsWith('/personal-Center/info')" src="~/assets/images/user3.png" alt="" srcset="" class="h-[20px]" />
|
||||||
|
<img v-else src="~/assets/images/个人.png" alt="" srcset="" class="h-[20px]" />
|
||||||
|
<span class="ml-[10px]">个人中心</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="pr-20px">
|
<div class="pr-[20px]">
|
||||||
<el-icon><ArrowRight /></el-icon>
|
<el-icon><ArrowRight /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
|
|
||||||
<nuxt-link to="/personal/profile" class="flex items-center justify-between py-14px">
|
<nuxt-link to="/personal-Center/personal-profile" class="flex items-center justify-between py-[14px]">
|
||||||
<div class="flex items-center pl-20px">
|
<div class="flex items-center pl-[20px]">
|
||||||
<img v-if="!route.path.startsWith('/personal/profile')" src="~/assets/images/user_zl.png" alt="" srcset="" class="h-16px" />
|
<img v-if="!route.path.startsWith('/personal-Center/personal-profile')" src="~/assets/images/user_zl.png" alt="" srcset="" class="h-[16px]" />
|
||||||
<img v-else src="~/assets/images/个人资料 (1).png" alt="" srcset="" class="h-16px" />
|
<img v-else src="~/assets/images/个人资料 (1).png" alt="" srcset="" class="h-[16px]" />
|
||||||
<span class="ml-10px">个人资料</span>
|
<span class="ml-[10px]">个人资料</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="pr-20px">
|
<div class="pr-[20px]">
|
||||||
<el-icon><ArrowRight /></el-icon>
|
<el-icon><ArrowRight /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
<nuxt-link to="/personal/account/security" class="flex items-center justify-between py-14px">
|
<nuxt-link to="/personal-Center/account-security" class="flex items-center justify-between py-[14px]">
|
||||||
<div class="flex items-center pl-20px">
|
<div class="flex items-center pl-[20px]">
|
||||||
<img v-if="!route.path.startsWith('/personal/account/security')" src="~/assets/images/account.png" alt="" srcset="" class="h-20px" />
|
<img v-if="!route.path.startsWith('/personal-Center/account-security')" src="~/assets/images/account.png" alt="" srcset="" class="h-[20px]" />
|
||||||
<img v-else src="~/assets/images/账户安全.png" alt="" srcset="" class="h-20px" />
|
<img v-else src="~/assets/images/账户安全.png" alt="" srcset="" class="h-[20px]" />
|
||||||
<span class="ml-14px">账户与安全</span>
|
<span class="ml-[14px]">账户与安全</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="pr-20px">
|
<div class="pr-[20px]">
|
||||||
<el-icon><ArrowRight /></el-icon>
|
<el-icon><ArrowRight /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
<nuxt-link to="/personal/resource/center" class="flex items-center justify-between py-14px">
|
<nuxt-link to="/personal-Center/resource-center" class="flex items-center justify-between py-[14px]">
|
||||||
<div class="flex items-center pl-20px">
|
<div class="flex items-center pl-[20px]">
|
||||||
<img v-if="!route.path.startsWith('/personal/resource/center')" src="~/assets/images/ziyuan.png" alt="" srcset="" class="h-18px" />
|
<img v-if="!route.path.startsWith('/personal-Center/resource-center')" src="~/assets/images/ziyuan.png" alt="" srcset="" class="h-[18px]" />
|
||||||
<img v-else src="~/assets/images/资源.png" alt="" srcset="" class="h-18px" />
|
<img v-else src="~/assets/images/资源.png" alt="" srcset="" class="h-[18px]" />
|
||||||
<span class="ml-12px">资源中心</span>
|
<span class="ml-[12px]">资源中心</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="pr-20px">
|
<div class="pr-[20px]">
|
||||||
<el-icon><ArrowRight /></el-icon>
|
<el-icon><ArrowRight /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
<nuxt-link to="/personal/trading/center" class="flex items-center justify-between py-14px">
|
<nuxt-link to="/personal-Center/trading-center" class="flex items-center justify-between py-[14px]">
|
||||||
<div class="flex items-center pl-20px">
|
<div class="flex items-center pl-[20px]">
|
||||||
<img v-if="!route.path.startsWith('/personal/trading/center')" src="~/assets/images/pay.png" alt="" srcset="" class="h-20px" />
|
<img v-if="!route.path.startsWith('/personal-Center/trading-center')" src="~/assets/images/pay.png" alt="" srcset="" class="h-[20px]" />
|
||||||
<img v-else src="~/assets/images/交易管理.png" alt="" srcset="" class="h-20px" />
|
<img v-else src="~/assets/images/交易管理.png" alt="" srcset="" class="h-[20px]" />
|
||||||
<span class="ml-12px">交易中心</span>
|
<span class="ml-[12px]">交易中心</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="pr-20px">
|
<div class="pr-[20px]">
|
||||||
<el-icon><ArrowRight /></el-icon>
|
<el-icon><ArrowRight /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
<nuxt-link to="/personal/center/message" class="flex items-center justify-between py-14px">
|
<nuxt-link to="/personal-Center/message-center" class="flex items-center justify-between py-[14px]">
|
||||||
<div class="flex items-center pl-20px">
|
<div class="flex items-center pl-[20px]">
|
||||||
<img v-if="!route.path.startsWith('/personal/center/message')" src="~/assets/images/message.png" alt="" srcset="" class="h-18px" />
|
<img v-if="!route.path.startsWith('/personal-Center/message-center')" src="~/assets/images/message.png" alt="" srcset="" class="h-[18px]" />
|
||||||
<img v-else src="~/assets/images/消息.png" alt="" srcset="" class="h-18px" />
|
<img v-else src="~/assets/images/消息.png" alt="" srcset="" class="h-[18px]" />
|
||||||
<span class="ml-14px">消息通知</span>
|
<span class="ml-[14px]">消息通知</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="pr-20px">
|
<div class="pr-[20px]">
|
||||||
<el-icon><ArrowRight /></el-icon>
|
<el-icon><ArrowRight /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
</div>
|
</div>
|
||||||
<div class="right mt-25px">
|
<div class="right mt-[25px]">
|
||||||
<NuxtPage />
|
<NuxtPage />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -54,9 +54,9 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { resetPassoword } from '~/api/login/index'
|
import { resetPassword } from '~/api/login/index'
|
||||||
import { sendSms } from '~/api/common/index'
|
import { sendSms } from '~/api/common/index'
|
||||||
import useUserStore from '~/store/user'
|
import useUserStore from '~/stores/user'
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
|
||||||
const activeName = ref('修改密码')
|
const activeName = ref('修改密码')
|
||||||
@ -75,7 +75,7 @@
|
|||||||
await formRef.value.validate()
|
await formRef.value.validate()
|
||||||
if (form.password !== form.passwordV2) return ElMessage.error('两次密码不一致')
|
if (form.password !== form.passwordV2) return ElMessage.error('两次密码不一致')
|
||||||
try {
|
try {
|
||||||
const res = await resetPassoword(form)
|
const res = await resetPassword(form)
|
||||||
const { code } = res
|
const { code } = res
|
||||||
if (code === 0) {
|
if (code === 0) {
|
||||||
ElMessage.success(`修改密码成功,请重新登录`)
|
ElMessage.success(`修改密码成功,请重新登录`)
|
||||||
@ -131,7 +131,7 @@
|
|||||||
import { upload } from '~/api/common'
|
import { upload } from '~/api/common'
|
||||||
import { sendSingleChat, conversationList, getChatDetail, clearUnreadMessage } from '~/api/channel/index'
|
import { sendSingleChat, conversationList, getChatDetail, clearUnreadMessage } from '~/api/channel/index'
|
||||||
import type { chatMessagesReq, msgType, PageResultSessionRespVO, PageResultMessageRespVO } from '~/api/channel/types'
|
import type { chatMessagesReq, msgType, PageResultSessionRespVO, PageResultMessageRespVO } from '~/api/channel/types'
|
||||||
import useUserStore from '~/store/user'
|
import useUserStore from '~/stores/user'
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="visible" width="800px" class="vip-dialog" align-center>
|
<el-dialog v-model="visible" width="800px" class="vip-dialog" align-center @close="handleClose">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="vip-modal-title">钱包充值</div>
|
<div class="vip-modal-title">钱包充值</div>
|
||||||
</template>
|
</template>
|
||||||
<div v-loading="loading" class="vip-cards">
|
<div v-loading="loading" class="vip-cards">
|
||||||
<div v-for="item in viplist" :key="item.id" class="vip-card">
|
<div v-for="item in viplist" :key="item.id" class="vip-card">
|
||||||
<div class="relative w-100% flex flex-col items-center">
|
<div class="relative w-[100%] flex flex-col items-center">
|
||||||
<div class="vip-card-header basic">
|
<div class="vip-card-header basic">
|
||||||
<div class="vip-card-title">{{ item.name }}</div>
|
<div class="vip-card-title">{{ item.name }}</div>
|
||||||
<!-- <div class="vip-card-subtitle">中小微企业</div> -->
|
<!-- <div class="vip-card-subtitle">中小微企业</div> -->
|
||||||
@ -25,8 +25,8 @@
|
|||||||
> -->
|
> -->
|
||||||
</ul>
|
</ul>
|
||||||
<div v-if="item.qrCodeUrl" class="vip-card-qrcode">
|
<div v-if="item.qrCodeUrl" class="vip-card-qrcode">
|
||||||
<el-icon class="absolute right--10px top-0px cursor-pointer" @click="item.qrCodeUrl = ''"><Close /></el-icon>
|
<el-icon class="absolute! right-[-10px] top-[0px] cursor-pointer" @click="item.qrCodeUrl = ''"><Close /></el-icon>
|
||||||
<qrcode-vue :value="item.qrCodeUrl" :size="140" level="H" />
|
<qrcode-vue :value="item.qrCodeUrl" :size="140" level="H" class="relative! left-[12px]" />
|
||||||
<div>请使用微信扫二维码</div>
|
<div>请使用微信扫二维码</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -44,7 +44,7 @@
|
|||||||
import type { AppPayWalletPackageRespVO } from '~/api/pay/types'
|
import type { AppPayWalletPackageRespVO } from '~/api/pay/types'
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import QrcodeVue from 'qrcode.vue'
|
import QrcodeVue from 'qrcode.vue'
|
||||||
import useUserStore from '~/store/user'
|
import useUserStore from '~/stores/user'
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -135,6 +135,14 @@
|
|||||||
clearInterval(interval.value)
|
clearInterval(interval.value)
|
||||||
interval.value = undefined
|
interval.value = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 关闭弹窗 */
|
||||||
|
const handleClose = () => {
|
||||||
|
visible.value = false
|
||||||
|
// 清空任务
|
||||||
|
clearInterval(interval.value)
|
||||||
|
interval.value = undefined
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@ -1,45 +1,45 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="box-border w-913px border border-[#EEEEEE] rounded-6px border-solid bg-[#FFFFFF] px-30px py-18px">
|
<div class="box-border w-[913px] border border-[#EEEEEE] rounded-[6px] border-solid bg-[#FFFFFF] px-[30px] py-[18px]">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<img :src="userStore.userInfoRes.avatar" alt="" srcset="" class="h-105px w-105px rounded-full" />
|
<img :src="userStore.userInfoRes.avatar" alt="" srcset="" class="h-[105px] w-[105px] rounded-full" />
|
||||||
<div class="ml-29px">
|
<div class="ml-[29px]">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<span class="text-20px text-[#333333] font-normal">Hi,{{ userStore.userInfoRes.nickname }}</span>
|
<span class="text-[20px] text-[#333333] font-normal">Hi,{{ userStore.userInfoRes.nickname }}</span>
|
||||||
<img v-if="userStore.userInfoRes.vipLevel === 1" src="~/assets/svg/vip.svg" alt="" class="relative top-2px ml-5px" />
|
<img v-if="userStore.userInfoRes.vipLevel === 1" src="~/assets/svg/vip.svg" alt="" class="relative top-[2px] ml-[5px]" />
|
||||||
<img v-if="userStore.userInfoRes.vipLevel === 2" src="~/assets/svg/svip.svg" alt="" class="relative top-2px ml-5px" />
|
<img v-if="userStore.userInfoRes.vipLevel === 2" src="~/assets/svg/svip.svg" alt="" class="relative top-[2px] ml-[5px]" />
|
||||||
<div
|
<div
|
||||||
class="ml-18px h-30px w-80px cursor-pointer border border-[#1A65FF] rounded-15px border-solid text-center text-14px text-[#1A65FF] font-normal line-height-30px"
|
class="ml-[18px] h-[30px] w-[80px] cursor-pointer border border-[#1A65FF] rounded-[15px] border-solid text-center text-[14px] text-[#1A65FF] font-normal line-height-[30px]"
|
||||||
@click="handleClick"
|
@click="handleClick"
|
||||||
>编辑资料</div
|
>编辑资料</div
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-20px flex items-center text-14px text-[#333333] font-normal">
|
<div class="mt-[20px] flex items-center text-[14px] text-[#333333] font-normal">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<img src="~/assets/images/cad_0 (1).png" alt="" srcset="" />
|
<img src="~/assets/images/cad_0 (1).png" alt="" srcset="" />
|
||||||
<span class="ml-4px">我的积分: {{ userStaticInfo?.pointCount || 0 }}</span>
|
<span class="ml-[4px]">我的积分: {{ userStaticInfo?.pointCount || 0 }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-37px flex items-center">
|
<div class="ml-[37px] flex items-center">
|
||||||
<img src="~/assets/images/cad_0 (2).png" alt="" srcset="" />
|
<img src="~/assets/images/cad_0 (2).png" alt="" srcset="" />
|
||||||
<span class="ml-4px">我的收藏: {{ userStaticInfo?.followCount || 0 }}</span>
|
<span class="ml-[4px]">我的收藏: {{ userStaticInfo?.followCount || 0 }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-37px flex items-center">
|
<div class="ml-[37px] flex items-center">
|
||||||
<img src="~/assets/images/cad_0 (3).png" alt="" srcset="" />
|
<img src="~/assets/images/cad_0 (3).png" alt="" srcset="" />
|
||||||
<span class="ml-4px">我的发布: {{ userStaticInfo?.projectCount || 0 }}</span>
|
<span class="ml-[4px]">我的发布: {{ userStaticInfo?.projectCount || 0 }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-37px flex items-center">
|
<div class="ml-[37px] flex items-center">
|
||||||
<img src="~/assets/images/cad_0 (4).png" alt="" srcset="" />
|
<img src="~/assets/images/cad_0 (4).png" alt="" srcset="" />
|
||||||
<span class="ml-4px">我的下载: {{ userStaticInfo?.downloadCount || 0 }}</span>
|
<span class="ml-[4px]">我的下载: {{ userStaticInfo?.downloadCount || 0 }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-30px flex items-center justify-around">
|
<div class="mt-[30px] flex items-center justify-around">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<img src="~/assets/images/info_1 (3).png" alt="" srcset="" />
|
<img src="~/assets/images/info_1 (3).png" alt="" srcset="" />
|
||||||
<img src="~/assets/images/info_1 (4).png" alt="" srcset="" class="absolute left-18px top-18px" />
|
<img src="~/assets/images/info_1 (4).png" alt="" srcset="" class="absolute left-[18px] top-[18px]" />
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-18px">
|
<div class="ml-[18px]">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<span class="info_num text-[#17A86D]">{{ userStaticInfo?.currencyCount || 0 }}</span>
|
<span class="info_num text-[#17A86D]">{{ userStaticInfo?.currencyCount || 0 }}</span>
|
||||||
<div class="info_pay cursor-pointer" @click="handlePay">充值</div>
|
<div class="info_pay cursor-pointer" @click="handlePay">充值</div>
|
||||||
@ -50,9 +50,9 @@
|
|||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<img src="~/assets/images/info_1 (5).png" alt="" srcset="" />
|
<img src="~/assets/images/info_1 (5).png" alt="" srcset="" />
|
||||||
<img src="~/assets/images/info_1 (6).png" alt="" srcset="" class="absolute left-18px top-22px" />
|
<img src="~/assets/images/info_1 (6).png" alt="" srcset="" class="absolute left-[18px] top-[22px]" />
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-18px">
|
<div class="ml-[18px]">
|
||||||
<div>
|
<div>
|
||||||
<span class="info_num text-[#328CD7]">{{ userStaticInfo?.previewCount || 0 }}</span>
|
<span class="info_num text-[#328CD7]">{{ userStaticInfo?.previewCount || 0 }}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -62,9 +62,9 @@
|
|||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<img src="~/assets/images/info_1 (1).png" alt="" srcset="" />
|
<img src="~/assets/images/info_1 (1).png" alt="" srcset="" />
|
||||||
<img src="~/assets/images/info_1 (2).png" alt="" srcset="" class="absolute left-20px top-18px" />
|
<img src="~/assets/images/info_1 (2).png" alt="" srcset="" class="absolute left-[20px] top-[18px]" />
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-18px">
|
<div class="ml-[18px]">
|
||||||
<div>
|
<div>
|
||||||
<span class="info_num text-[#FFC415]">{{ userStaticInfo?.revenueCount || 0 }}</span>
|
<span class="info_num text-[#FFC415]">{{ userStaticInfo?.revenueCount || 0 }}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -74,20 +74,20 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<div class="mt-23px box-border h-183px w-913px border border-[#EEEEEE] rounded-6px border-solid bg-[#FFFFFF] px-30px py-21px">
|
<div class="mt-[23px] box-border h-[183px] w-[913px] border border-[#EEEEEE] rounded-[6px] border-solid bg-[#FFFFFF] px-[30px] py-[21px]">
|
||||||
<div class="title">快捷入口</div>
|
<div class="title">快捷入口</div>
|
||||||
<div class="mt-20px flex items-center">
|
<div class="mt-[20px] flex items-center">
|
||||||
<div class="info_item cursor-pointer" @click="handleClickPush('/upnew/drawe')">
|
<div class="info_item cursor-pointer" @click="handleClickPush('/upnew')">
|
||||||
<img src="~/assets/images/fabu_2 (3).png" alt="" srcset="" />
|
<img src="~/assets/images/fabu_2 (3).png" alt="" srcset="" />
|
||||||
<div class="mt-10px">发布资源</div>
|
<div class="mt-[10px]">发布资源</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="info_item ml-31px cursor-pointer" @click="handleClickPush('/communication/channel')">
|
<div class="info_item ml-[31px] cursor-pointer" @click="handleClickPush('/channel')">
|
||||||
<img src="~/assets/images/fabu_2 (1).png" alt="" srcset="" />
|
<img src="~/assets/images/fabu_2 (1).png" alt="" srcset="" />
|
||||||
<div class="mt-10px">交流频道</div>
|
<div class="mt-[10px]">交流频道</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="info_item ml-31px cursor-pointer" @click="handleService">
|
<div class="info_item ml-[31px] cursor-pointer" @click="handleService">
|
||||||
<img src="~/assets/images/fabu_2 (2).png" alt="" srcset="" />
|
<img src="~/assets/images/fabu_2 (2).png" alt="" srcset="" />
|
||||||
<div class="mt-10px">消息</div>
|
<div class="mt-[10px]">消息</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -107,7 +107,7 @@
|
|||||||
import Message from './components/message.vue'
|
import Message from './components/message.vue'
|
||||||
import InfoEcharts from './info-echarts.vue'
|
import InfoEcharts from './info-echarts.vue'
|
||||||
import Pay from './components/pay.vue'
|
import Pay from './components/pay.vue'
|
||||||
import useUserStore from '~/store/user'
|
import useUserStore from '~/stores/user'
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
|
||||||
// 路由跳转
|
// 路由跳转
|
||||||
@ -123,7 +123,7 @@
|
|||||||
fetchUserStatistics()
|
fetchUserStatistics()
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
router.push({ path: '/personal/profile' })
|
router.push({ path: '/personal-Center/personal-profile' })
|
||||||
}
|
}
|
||||||
|
|
||||||
const payVisible = ref(false)
|
const payVisible = ref(false)
|
||||||
@ -1,10 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="box-border h-1082px w-913px border border-[#EEEEEE] rounded-6px border-solid bg-[#FFFFFF] px-30px py-21px">
|
<div class="box-border h-[782px] w-[913px] border border-[#EEEEEE] rounded-[6px] border-solid bg-[#FFFFFF] px-[30px] py-[21px]">
|
||||||
<div class="flex items-center justify-between border-b-1px border-b-[#eeeeee] border-b-solid pb-18px">
|
<div class="flex items-center justify-between border-b-[1px] border-b-[#eeeeee] border-b-solid pb-[18px]">
|
||||||
<div class="text-16px text-[#333333] font-normal">个人资料</div>
|
<div class="text-[16px] text-[#333333] font-normal">个人资料</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<!-- <img src="~/assets/images/fans.png" alt="" srcset="" /> -->
|
<!-- <img src="~/assets/images/fans.png" alt="" srcset="" /> -->
|
||||||
<span class="ml-8px text-14px text-[#333333] font-normal"></span>
|
<span class="ml-[8px] text-[14px] text-[#333333] font-normal"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="user-profile-container">
|
<div class="user-profile-container">
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<el-upload class="avatar-uploader" action="#" :show-file-list="false" :auto-upload="false" :on-change="handleAvatarChange">
|
<el-upload class="avatar-uploader" action="#" :show-file-list="false" :auto-upload="false" :on-change="handleAvatarChange">
|
||||||
<div class="flex flex-col items-center">
|
<div class="flex flex-col items-center">
|
||||||
<el-avatar :size="100" :src="userForm.avatar" />
|
<el-avatar :size="100" :src="userForm.avatar" />
|
||||||
<div class="mt-15px">
|
<div class="mt-[15px]">
|
||||||
<el-button type="primary" plain>更改头像</el-button>
|
<el-button type="primary" plain>更改头像</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -24,7 +24,7 @@
|
|||||||
<!-- User information section -->
|
<!-- User information section -->
|
||||||
<el-form-item label="用户名:" prop="nickname">
|
<el-form-item label="用户名:" prop="nickname">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<el-input v-model="userForm.nickname" class="w-247px" />
|
<el-input v-model="userForm.nickname" class="w-[247px]" />
|
||||||
<el-button type="primary" class="verify-btn" @click="handleVerify">实名认证</el-button>
|
<el-button type="primary" class="verify-btn" @click="handleVerify">实名认证</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -38,37 +38,37 @@
|
|||||||
|
|
||||||
<el-form-item label="手机号:" prop="phone">
|
<el-form-item label="手机号:" prop="phone">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<el-input v-model="userForm.phone" disabled class="w-247px" />
|
<el-input v-model="userForm.phone" disabled class="w-[247px]" />
|
||||||
<!-- <el-link type="primary" class="modify-link">修改</el-link> -->
|
<!-- <el-link type="primary" class="modify-link">修改</el-link> -->
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="电子邮箱:" prop="email">
|
<el-form-item label="电子邮箱:" prop="email">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<el-input v-model="userForm.email" placeholder="请输入电子邮箱" class="w-247px" />
|
<el-input v-model="userForm.email" placeholder="请输入电子邮箱" class="w-[247px]" />
|
||||||
<!-- <el-link type="primary" class="modify-link">绑定</el-link> -->
|
<!-- <el-link type="primary" class="modify-link">绑定</el-link> -->
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<el-form-item label="所在地区:" prop="isDomestic">
|
<el-form-item label="所在地区:" prop="isDomestic">
|
||||||
<el-select v-model="userForm.isDomestic" placeholder="请选择" class="w-120px!" @change="handleCountryChange">
|
<el-select v-model="userForm.isDomestic" placeholder="请选择" class="w-[120px]!" @change="handleCountryChange">
|
||||||
<el-option label="国内" :value="1"></el-option>
|
<el-option label="国内" :value="1"></el-option>
|
||||||
<el-option label="国外" :value="0"></el-option>
|
<el-option label="国外" :value="0"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label-width="6px" prop="province">
|
<el-form-item label-width="6px" prop="province">
|
||||||
<el-select v-model="userForm.province" placeholder="请选择省份" class="w-120px" @change="handleProvinceChange">
|
<el-select v-model="userForm.province" placeholder="请选择省份" class="w-[120px]!" @change="handleProvinceChange">
|
||||||
<el-option v-for="item in provinceList" :key="item.id" :label="item.name" :value="item.id" />
|
<el-option v-for="item in provinceList" :key="item.id" :label="item.name" :value="item.id" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label-width="6px" prop="city">
|
<el-form-item label-width="6px" prop="city">
|
||||||
<el-select v-model="userForm.city" placeholder="请选择城市" class="w-120px" @change="handleCityChange">
|
<el-select v-model="userForm.city" placeholder="请选择城市" class="w-[120px]!" @change="handleCityChange">
|
||||||
<el-option v-for="item in cityList" :key="item.id" :label="item.name" :value="item.id" />
|
<el-option v-for="item in cityList" :key="item.id" :label="item.name" :value="item.id" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label-width="6px" prop="county">
|
<el-form-item label-width="6px" prop="county">
|
||||||
<el-select v-model="userForm.county" placeholder="请选择区县" class="w-120px">
|
<el-select v-model="userForm.county" placeholder="请选择区县" class="w-[120px]!">
|
||||||
<el-option v-for="item in countyList" :key="item.id" :label="item.name" :value="item.id" />
|
<el-option v-for="item in countyList" :key="item.id" :label="item.name" :value="item.id" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -83,7 +83,7 @@
|
|||||||
filterable
|
filterable
|
||||||
remote
|
remote
|
||||||
placeholder="请输入搜索标签"
|
placeholder="请输入搜索标签"
|
||||||
class="w-498px!"
|
class="w-[498px]!"
|
||||||
>
|
>
|
||||||
<el-option v-for="(item, index) in labelsList" :key="index" :label="item" :value="item" />
|
<el-option v-for="(item, index) in labelsList" :key="index" :label="item" :value="item" />
|
||||||
</el-select>
|
</el-select>
|
||||||
@ -97,9 +97,9 @@
|
|||||||
:size="1"
|
:size="1"
|
||||||
tips="上传图片支持jpg/gif/png格式、第一张为封面图片、每张图片大小不得超过1M"
|
tips="上传图片支持jpg/gif/png格式、第一张为封面图片、每张图片大小不得超过1M"
|
||||||
>
|
>
|
||||||
<div class="h-77px w-161px flex items-center justify-center bg-[#fafafa]">
|
<div class="h-[77px] w-[161px] flex items-center justify-center bg-[#fafafa]">
|
||||||
<el-icon class="text-[#999999]"><Plus /></el-icon>
|
<el-icon class="text-[#999999]"><Plus /></el-icon>
|
||||||
<div class="ml-4px mt-2px text-14px text-[#999999] font-normal">上传图纸</div>
|
<div class="ml-[4px] mt-[2px] text-[14px] text-[#999999] font-normal">上传图纸</div>
|
||||||
</div>
|
</div>
|
||||||
</KlUploader>
|
</KlUploader>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -109,27 +109,27 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" class="w-120px !h-37px" @click="submitForm">提交</el-button>
|
<el-button type="primary" class="w-[120px] !h-[37px]" :loading="submitLoading" @click="submitForm">提交</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between border-b-1px border-b-[#eeeeee] border-b-solid pb-18px">
|
<!-- <div class="flex items-center justify-between border-b-[1px] border-b-[#eeeeee] border-b-solid pb-[18px]">
|
||||||
<div class="text-16px text-[#333333] font-normal">社交帐号绑定</div>
|
<div class="text-[16px] text-[#333333] font-normal">社交帐号绑定</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col justify-center text-14px text-[#333333] font-normal">
|
<div class="flex flex-col justify-center text-[14px] text-[#333333] font-normal">
|
||||||
<div class="mt-30px flex items-center">
|
<div class="mt-[30px] flex items-center">
|
||||||
<img src="~/assets/images/qq-v2.png" alt="" srcset="" class="h-35px w-34px" />
|
<img src="~/assets/images/qq-v2.png" alt="" srcset="" class="h-[35px] w-[34px]" />
|
||||||
<div class="ml-19px">QQ</div>
|
<div class="ml-[19px]">QQ</div>
|
||||||
<div class="ml-100px flex items-center"><div class="w-90px">QQ昵称:</div><div class="w-180px">xxx</div></div>
|
<div class="ml-[100px] flex items-center"><div class="w-[90px]">QQ昵称:</div><div class="w-[180px]">xxx</div></div>
|
||||||
<div class="btn">绑定</div>
|
<div class="btn">绑定</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-30px flex items-center">
|
<div class="mt-[30px] flex items-center">
|
||||||
<img src="~/assets/images/weixin-v2.png" alt="" srcset="" class="h-35px w-34px" />
|
<img src="~/assets/images/weixin-v2.png" alt="" srcset="" class="h-[35px] w-[34px]" />
|
||||||
<div class="ml-19px">微信</div>
|
<div class="ml-[19px]">微信</div>
|
||||||
<div class="ml-95px flex items-center"><div class="w-90px">微信昵称:</div><div class="w-180px">xxx</div></div>
|
<div class="ml-[95px] flex items-center"><div class="w-[90px]">微信昵称:</div><div class="w-[180px]">xxx</div></div>
|
||||||
<div class="btn">绑定</div>
|
<div class="btn">绑定</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
<verifyDialog ref="verifyDialogRef" />
|
<verifyDialog ref="verifyDialogRef" />
|
||||||
</template>
|
</template>
|
||||||
@ -281,11 +281,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 提交表单
|
// 提交表单
|
||||||
|
const submitLoading = ref(false)
|
||||||
const submitForm = async () => {
|
const submitForm = async () => {
|
||||||
if (!userFormRef.value) return
|
if (!userFormRef.value) return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await userFormRef.value.validate()
|
await userFormRef.value.validate()
|
||||||
|
submitLoading.value = true
|
||||||
const res = userForm.id ? await updateUserExtend(userForm) : await userExtend(userForm)
|
const res = userForm.id ? await updateUserExtend(userForm) : await userExtend(userForm)
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
ElMessage.success('个人信息提交成功')
|
ElMessage.success('个人信息提交成功')
|
||||||
@ -295,6 +297,8 @@
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Validation failed:', error)
|
console.error('Validation failed:', error)
|
||||||
ElMessage.error('表单验证失败,请检查输入')
|
ElMessage.error('表单验证失败,请检查输入')
|
||||||
|
} finally {
|
||||||
|
submitLoading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,7 +40,7 @@
|
|||||||
import downloadTable from './components/download-table.vue'
|
import downloadTable from './components/download-table.vue'
|
||||||
import favoriteTable from './components/favorite-table.vue'
|
import favoriteTable from './components/favorite-table.vue'
|
||||||
import browseTable from './components/browse-table.vue'
|
import browseTable from './components/browse-table.vue'
|
||||||
import useUserStore from '~/store/user'
|
import useUserStore from '~/stores/user'
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
|
||||||
const activeName = ref('我的上传')
|
const activeName = ref('我的上传')
|
||||||
@ -5,20 +5,20 @@
|
|||||||
<div class="profile-header">
|
<div class="profile-header">
|
||||||
<div class="profile-container">
|
<div class="profile-container">
|
||||||
<div class="avatar-container">
|
<div class="avatar-container">
|
||||||
<el-image :src="userForm.avatar" alt="用户头像" class="avatar mt-4px" fit="cover" />
|
<el-image :src="userForm.avatar" alt="用户头像" class="avatar mt-[4px]" fit="cover" />
|
||||||
</div>
|
</div>
|
||||||
<div class="user-info">
|
<div class="user-info">
|
||||||
<h2 class="username">{{ userForm.nickname }}</h2>
|
<h2 class="username">{{ userForm.nickname }}</h2>
|
||||||
<!-- <div class="education">手机号码:{{ userForm.phone }}</div> -->
|
<!-- <div class="education">手机号码:{{ userForm.phone }}</div> -->
|
||||||
<div class="stats">
|
<div class="stats">
|
||||||
技能标签:<el-tag v-for="label in userForm.labels" :key="label" type="primary" class="mr-10px" size="small">{{ label }}</el-tag>
|
技能标签:<el-tag v-for="label in userForm.labels" :key="label" type="primary" class="mr-[10px]" size="small">{{ label }}</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div class="description">{{ userForm.description }}</div>
|
<div class="description">{{ userForm.description }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="items-flex-start mx-auto mt-20px max-w-[1200px] flex justify-center">
|
<div class="items-flex-start mx-auto mt-[20px] max-w-[1200px] flex justify-center">
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<!-- 导航标签 -->
|
<!-- 导航标签 -->
|
||||||
<div class="nav-tabs">
|
<div class="nav-tabs">
|
||||||
@ -30,27 +30,27 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 作品展示区 -->
|
<!-- 作品展示区 -->
|
||||||
<div class="content w-800px">
|
<div class="content w-[800px]">
|
||||||
<el-table v-loading="result.loading" :data="result.tableList" style="width: 100%" class="mt-14px">
|
<el-table v-loading="result.loading" :data="result.tableList" style="width: 100%" class="mt-[14px]">
|
||||||
<el-table-column prop="date" label="文件信息">
|
<el-table-column prop="date" label="文件信息">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<el-image :src="scope.row.iconUrl" fit="cover" alt="" srcset="" class="h-91px w-181px rd-4px" />
|
<el-image :src="scope.row.iconUrl" fit="cover" alt="" srcset="" class="h-[91px] w-[181px] rd-[4px]" />
|
||||||
<div class="ml-17px">
|
<div class="ml-[17px]">
|
||||||
<div class="text-16px text-[#333333] font-normal">{{ scope.row.title }}</div>
|
<div class="text-[16px] text-[#333333] font-normal">{{ scope.row.title }}</div>
|
||||||
<div class="text-14px text-[#666] font-normal my-10px!">{{ dayjs(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</div>
|
<div class="text-[14px] text-[#666] font-normal my-[10px]!">{{ dayjs(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<img src="~/assets/images/look.png" alt="" srcset="" class="h-17px" />
|
<img src="~/assets/images/look.png" alt="" srcset="" class="h-[17px]" />
|
||||||
<span class="ml-4px">{{ scope.row.previewPoint }}</span>
|
<span class="ml-[4px]">{{ scope.row.previewPoint }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-13px flex items-center">
|
<div class="ml-[13px] flex items-center">
|
||||||
<img src="~/assets/images/add.png" alt="" srcset="" class="h-23px" />
|
<img src="~/assets/images/add.png" alt="" srcset="" class="h-[23px]" />
|
||||||
<span class="ml-4px">{{ scope.row.hotPoint }}</span>
|
<span class="ml-[4px]">{{ scope.row.hotPoint }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-13px flex items-center">
|
<div class="ml-[13px] flex items-center">
|
||||||
<img src="~/assets/images/chat.png" alt="" srcset="" class="h-17px" />
|
<img src="~/assets/images/chat.png" alt="" srcset="" class="h-[17px]" />
|
||||||
<span class="ml-4px">{{ scope.row.commentsPoint }}</span>
|
<span class="ml-[4px]">{{ scope.row.commentsPoint }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -70,7 +70,7 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<div class="mt-10px flex justify-center">
|
<div class="mt-[10px] flex justify-center">
|
||||||
<el-pagination
|
<el-pagination
|
||||||
v-model:current-page="query.pageNo"
|
v-model:current-page="query.pageNo"
|
||||||
v-model:page-size="query.pageSize"
|
v-model:page-size="query.pageSize"
|
||||||
@ -91,10 +91,10 @@
|
|||||||
<div
|
<div
|
||||||
v-for="item in mainWork"
|
v-for="item in mainWork"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
class="flex cursor-pointer items-center justify-between px-10px py-4px hover:bg-#f5f5f5"
|
class="flex cursor-pointer items-center justify-between px-[10px] py-[4px] hover:bg-[#f5f5f5]"
|
||||||
@click="handleClickV2(item.id)"
|
@click="handleClickV2(item.id)"
|
||||||
>
|
>
|
||||||
<div class="ellipsis text-15px text-[#333333] font-normal">{{ item.title }}发货速度发货速度开发还是看东方航空</div>
|
<div class="ellipsis text-[15px] text-[#333333] font-normal">{{ item.title }}发货速度发货速度开发还是看东方航空</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -249,7 +249,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleClickV2 = (id: string | number) => {
|
const handleClickV2 = (id: string | number) => {
|
||||||
navigateTo(`/down-drawe-detail?id=${id}`) // 修改为在新窗口打开
|
navigateTo(`/down-drawe-detail/${id}`) // 修改为在新窗口打开
|
||||||
}
|
}
|
||||||
// 获取最新发布
|
// 获取最新发布
|
||||||
const mainWork = ref<ProjectDrawMemberRespVO[]>([])
|
const mainWork = ref<ProjectDrawMemberRespVO[]>([])
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<KlNavTab />
|
<KlNavTab />
|
||||||
<div class="sign-content">
|
<div class="sign-content w-1440px ma-auto">
|
||||||
<!-- 顶部统计 -->
|
<!-- 顶部统计 -->
|
||||||
<div class="sign-header">
|
<div class="sign-header">
|
||||||
<div class="sign-icon">
|
<div class="sign-icon">
|
||||||
@ -18,7 +18,7 @@
|
|||||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="sign-center ml-10px">
|
<div class="sign-center ml-[10px]">
|
||||||
<el-button type="success" class="sign-btn" @click="handleClickSign"> 立即签到 </el-button>
|
<el-button type="success" class="sign-btn" @click="handleClickSign"> 立即签到 </el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -40,7 +40,7 @@
|
|||||||
<div>积分</div>
|
<div>积分</div>
|
||||||
<div>发生时间</div>
|
<div>发生时间</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-for="item in result.list" :key="item.id" class="table-row">
|
<div v-for="item in result?.list" :key="item.id" class="table-row">
|
||||||
<!-- <div class="avatar"> -->
|
<!-- <div class="avatar"> -->
|
||||||
<!-- <img :src="item.avatar" alt="avatar" /> -->
|
<!-- <img :src="item.avatar" alt="avatar" /> -->
|
||||||
<!-- <span>{{ item.nickname }}</span> -->
|
<!-- <span>{{ item.nickname }}</span> -->
|
||||||
@ -52,12 +52,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 分页组件 -->
|
<!-- 分页组件 -->
|
||||||
<div class="mt-10px flex justify-center">
|
<div class="mt-[10px] flex justify-center">
|
||||||
<el-pagination
|
<el-pagination
|
||||||
v-model:current-page="query.pageNo"
|
v-model:current-page="query.pageNo"
|
||||||
:page-size="query.pageSize"
|
:page-size="query.pageSize"
|
||||||
layout="prev, pager, next"
|
layout="prev, pager, next"
|
||||||
:total="result.total"
|
:total="result?.total"
|
||||||
@current-change="handleCurrentChange"
|
@current-change="handleCurrentChange"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -69,21 +69,21 @@
|
|||||||
import { Search } from '@element-plus/icons-vue'
|
import { Search } from '@element-plus/icons-vue'
|
||||||
import { signIn, getUserPointPage } from '~/api/personal-center/index'
|
import { signIn, getUserPointPage } from '~/api/personal-center/index'
|
||||||
import type { PageResultMemberPointRecordRespVO } from '~/api/personal-center/types'
|
import type { PageResultMemberPointRecordRespVO } from '~/api/personal-center/types'
|
||||||
import useUserStore from '~/store/user'
|
import useUserStore from '~/stores/user'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
const userStore = useUserStore()
|
const user = useUserInfo()
|
||||||
|
|
||||||
const query = reactive({
|
const query = reactive({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
userId: userStore.userId,
|
userId: user.value.id,
|
||||||
title: '',
|
title: '',
|
||||||
})
|
})
|
||||||
|
|
||||||
const result = reactive<PageResultMemberPointRecordRespVO>({
|
// const result = reactive<PageResultMemberPointRecordRespVO>({
|
||||||
total: 0,
|
// total: 0,
|
||||||
list: [],
|
// list: [],
|
||||||
})
|
// })
|
||||||
// const signList = ref([
|
// const signList = ref([
|
||||||
// {
|
// {
|
||||||
// avatar: 'https://dummyimage.com/40x40/ccc/fff.png&text=美',
|
// avatar: 'https://dummyimage.com/40x40/ccc/fff.png&text=美',
|
||||||
@ -115,14 +115,25 @@
|
|||||||
getUserPointPageList()
|
getUserPointPageList()
|
||||||
}
|
}
|
||||||
|
|
||||||
const getUserPointPageList = async () => {
|
const { data: result, refresh: getUserPointPageList } = await useAsyncData(
|
||||||
|
'getUserPointPage',
|
||||||
|
async () => {
|
||||||
const res = await getUserPointPage(query)
|
const res = await getUserPointPage(query)
|
||||||
if (res.code === 0) {
|
return res.data
|
||||||
result.list = res.data.list
|
},
|
||||||
result.total = res.data.total
|
{
|
||||||
|
immediate: true, // 立即请求
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
getUserPointPageList()
|
|
||||||
|
// const getUserPointPageList = async () => {
|
||||||
|
// const res = await getUserPointPage(query)
|
||||||
|
// if (res.code === 0) {
|
||||||
|
// result.list = res.data.list
|
||||||
|
// result.total = res.data.total
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// getUserPointPageList()
|
||||||
|
|
||||||
const handleClickSign = async () => {
|
const handleClickSign = async () => {
|
||||||
const res = await signIn()
|
const res = await signIn()
|
||||||
|
|||||||
@ -0,0 +1,126 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 导航 -->
|
||||||
|
<SeoHead title="工程设计文本下载_CAD设计图纸资源库" />
|
||||||
|
<KlNavTab active="文本" :type="2" />
|
||||||
|
<div class="ma-auto w-[1440px]">
|
||||||
|
<!-- 图纸分类 -->
|
||||||
|
<KlWallpaperCategory v-model="query" v-model:level="level" :type="2" />
|
||||||
|
<!-- 推荐栏目 -->
|
||||||
|
<RecommendedColumnsV2 v-model="query" v-model:result="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="[12, 24, 48]"
|
||||||
|
:total="result?.total"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
@size-change="handleClickSize"
|
||||||
|
@current-change="handeClickCurrent"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import KlNavTab from '~/components/kl-nav-tab/index.vue'
|
||||||
|
import KlWallpaperCategory from '~/components/kl-wallpaper-category/index.vue'
|
||||||
|
import RecommendedColumnsV2 from '~/components/text-components/RecommendedColumnsV2.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: 2,
|
||||||
|
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 handleClickSize = (val: number) => {
|
||||||
|
query.value.pageSize = val
|
||||||
|
// getPage()
|
||||||
|
navigateTo(`/text/${query.value.projectType}/${query.value.pageNo}/${val}/${query.value.editions}/${query.value.source}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handeClickCurrent = (val: number) => {
|
||||||
|
query.value.pageNo = val
|
||||||
|
// getPage()
|
||||||
|
navigateTo(`/text/${query.value.projectType}/${val}/${query.value.pageSize}/${query.value.editions}/${query.value.source}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data: result, refresh: getPage } = useAsyncData(
|
||||||
|
`draw-page-list-${query.value.projectType}-${query.value.editions}-${query.value.source}-${query.value.pageNo}-${query.value.pageSize}`,
|
||||||
|
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(`/text/${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>
|
||||||
@ -1,7 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- 导航 -->
|
<!-- 导航 -->
|
||||||
|
<SeoHead title="工程设计文本下载_CAD设计图纸资源库" />
|
||||||
<KlNavTab active="文本" :type="2" />
|
<KlNavTab active="文本" :type="2" />
|
||||||
<div class="ma-auto w-1440px">
|
<div class="ma-auto w-[1440px]">
|
||||||
<!-- 图纸分类 -->
|
<!-- 图纸分类 -->
|
||||||
<KlWallpaperCategory v-model="query" v-model:level="level" :type="2" />
|
<KlWallpaperCategory v-model="query" v-model:level="level" :type="2" />
|
||||||
<!-- 推荐栏目 -->
|
<!-- 推荐栏目 -->
|
||||||
@ -9,12 +10,12 @@
|
|||||||
<!-- 精选专题 -->
|
<!-- 精选专题 -->
|
||||||
<!-- <FeaturedSpecials></FeaturedSpecials> -->
|
<!-- <FeaturedSpecials></FeaturedSpecials> -->
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<div class="mt-10px flex justify-center">
|
<div class="mt-[10px] flex justify-center">
|
||||||
<el-pagination
|
<el-pagination
|
||||||
v-model:current-page="query.pageNo"
|
v-model:current-page="query.pageNo"
|
||||||
v-model:page-size="query.pageSize"
|
v-model:page-size="query.pageSize"
|
||||||
:page-sizes="[12, 24, 48]"
|
:page-sizes="[12, 24, 48]"
|
||||||
:total="result.total"
|
:total="result?.total"
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
@size-change="handeChangeSize"
|
@size-change="handeChangeSize"
|
||||||
@current-change="handeChangeCurrent"
|
@current-change="handeChangeCurrent"
|
||||||
@ -25,7 +26,7 @@
|
|||||||
<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 KlWallpaperCategory from '~/components/kl-wallpaper-category/index.vue'
|
import KlWallpaperCategory from '~/components/kl-wallpaper-category/index.vue'
|
||||||
import RecommendedColumnsV2 from './components/RecommendedColumnsV2.vue'
|
import RecommendedColumnsV2 from '~/components/text-components/RecommendedColumnsV2.vue'
|
||||||
// import FeaturedSpecials from './components/FeaturedSpecials.vue'
|
// import FeaturedSpecials from './components/FeaturedSpecials.vue'
|
||||||
|
|
||||||
import { reactive, watch, ref } from 'vue'
|
import { reactive, watch, ref } from 'vue'
|
||||||
@ -39,57 +40,76 @@
|
|||||||
? JSON.parse(route.query.level as string)
|
? JSON.parse(route.query.level as string)
|
||||||
: [
|
: [
|
||||||
{
|
{
|
||||||
id: '0',
|
id: -1,
|
||||||
name: '文本库',
|
name: '文本库',
|
||||||
isChildren: false,
|
isChildren: false,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
const query = reactive<pageReq>({
|
const query = ref<pageReq>({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 12,
|
pageSize: 12,
|
||||||
projectType: '',
|
projectType: '-1',
|
||||||
editions: '',
|
editions: '-1',
|
||||||
source: '',
|
source: -1,
|
||||||
type: 2,
|
type: 2,
|
||||||
})
|
})
|
||||||
const result = reactive<pageRes>({
|
// const result = reactive<pageRes>({
|
||||||
list: [],
|
// list: [],
|
||||||
total: 0,
|
// total: 0,
|
||||||
})
|
// })
|
||||||
|
|
||||||
// 如果id存在,则设置projectType
|
// 如果id存在,则设置projectType
|
||||||
if (level.value.length) {
|
if (level.value.length) {
|
||||||
query.projectType = level.value[level.value.length - 1].id || ''
|
// query.projectType = level.value[level.value.length - 1].id || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const getPage = () => {
|
const { data: result } = useAsyncData(
|
||||||
page(query).then((res) => {
|
`draw-page-list-${query.value.projectType}-${query.value.editions}-${query.value.source}-${query.value.pageNo}-${query.value.pageSize}`,
|
||||||
const { data, code } = res
|
async () => {
|
||||||
if (code === 0) {
|
const res = await page({
|
||||||
result.list = data.list
|
...query.value,
|
||||||
result.total = data.total
|
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,
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
getPage()
|
// const getPage = () => {
|
||||||
|
// page(query).then((res) => {
|
||||||
|
// const { data, code } = res
|
||||||
|
// if (code === 0) {
|
||||||
|
// result.list = data.list
|
||||||
|
// result.total = data.total
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
// getPage()
|
||||||
|
|
||||||
const handeChangeSize = (val: number) => {
|
const handeChangeSize = (val: number) => {
|
||||||
query.pageSize = val
|
query.value.pageSize = val
|
||||||
query.pageNo = 1
|
// query.pageNo = 1
|
||||||
getPage()
|
// getPage()
|
||||||
|
navigateTo(`/text/${query.value.projectType}/${query.value.pageNo}/${val}/${query.value.editions}/${query.value.source}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handeChangeCurrent = (val: number) => {
|
const handeChangeCurrent = (val: number) => {
|
||||||
query.pageNo = val
|
query.value.pageNo = val
|
||||||
getPage()
|
// getPage()
|
||||||
|
navigateTo(`/text/${query.value.projectType}/${val}/${query.value.pageSize}/${query.value.editions}/${query.value.source}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
watch([() => query.projectType, () => query.editions, () => query.source], (val) => {
|
watch([() => query.value.projectType, () => query.value.editions, () => query.value.source], (val) => {
|
||||||
if (val) {
|
if (val) {
|
||||||
getPage()
|
// getPage()
|
||||||
|
navigateTo(`/text/${query.value.projectType}/1/${query.value.pageSize}/${query.value.editions}/${query.value.source}`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<KlNavTab />
|
<KlNavTab />
|
||||||
<div class="mx-auto mt-30px box-border w-1200px border border-[#EEEEEE] rounded-12px border-solid bg-white px-30px py-40px">
|
<div class="mx-auto mt-[30px] box-border w-[1200px] border border-[#EEEEEE] rounded-[12px] border-solid bg-white px-[30px] py-[40px]">
|
||||||
<el-form ref="formRef" :model="form" label-width="110px" size="large">
|
<el-form ref="formRef" :model="form" label-width="110px" size="large">
|
||||||
<el-form-item label-width="110px" label="标题:" prop="title" :rules="{ required: true, message: '请输入标题', trigger: ['blur', 'change'] }">
|
<el-form-item label-width="110px" label="标题:" prop="title" :rules="{ required: true, message: '请输入标题', trigger: ['blur', 'change'] }">
|
||||||
<el-input v-model="form.title" placeholder="请输入标题" class="w-361px!" maxlength="128"></el-input>
|
<el-input v-model="form.title" placeholder="请输入标题" class="w-[361px]!" maxlength="128"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label-width="110px" label="分类:" prop="projectType" :rules="{ required: true, message: '请选择分类', trigger: ['blur', 'change'] }">
|
<el-form-item label-width="110px" label="分类:" prop="projectType" :rules="{ required: true, message: '请选择分类', trigger: ['blur', 'change'] }">
|
||||||
<el-select v-model="form.projectType" placeholder="请选择分类" class="w-361px!" multiple>
|
<el-select v-model="form.projectType" placeholder="请选择分类" class="w-[361px]!" multiple>
|
||||||
<el-option v-for="(item, index) in projectTypeList" :key="index" :label="item.name" :value="item.id" />
|
<el-option v-for="(item, index) in projectTypeList" :key="index" :label="item.name" :value="item.id" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -20,13 +20,13 @@
|
|||||||
filterable
|
filterable
|
||||||
remote
|
remote
|
||||||
placeholder="请输入搜索标签"
|
placeholder="请输入搜索标签"
|
||||||
class="w-361px!"
|
class="w-[361px]!"
|
||||||
>
|
>
|
||||||
<el-option v-for="(item, index) in labelsList" :key="index" :label="item" :value="item" />
|
<el-option v-for="(item, index) in labelsList" :key="index" :label="item" :value="item" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label-width="110px" label="金币:" prop="points" :rules="{ required: true, message: '请输入金币', trigger: ['blur', 'change'] }">
|
<el-form-item label-width="110px" label="金币:" prop="points" :rules="{ required: true, message: '请输入金币', trigger: ['blur', 'change'] }">
|
||||||
<el-input-number v-model="form.points" :controls="false" :precision="0" :min="0" placeholder="请输入金币" class="w-361px! text-left!"></el-input-number>
|
<el-input-number v-model="form.points" :controls="false" :precision="0" :min="0" placeholder="请输入金币" class="w-[361px]! text-left!"></el-input-number>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item
|
<el-form-item
|
||||||
@ -43,9 +43,9 @@
|
|||||||
tips="上传图片支持jpg/gif/png格式、第一张为封面图片、每张图片大小不得超过1M"
|
tips="上传图片支持jpg/gif/png格式、第一张为封面图片、每张图片大小不得超过1M"
|
||||||
@validate="formRef.validateField('coverImages')"
|
@validate="formRef.validateField('coverImages')"
|
||||||
>
|
>
|
||||||
<div class="h-77px w-161px flex items-center justify-center border border-[#cdd0d6] rounded-1px border-dashed bg-[#fafafa]">
|
<div class="h-[77px] w-[161px] flex items-center justify-center border border-[#cdd0d6] rounded-[1px] border-dashed bg-[#fafafa]">
|
||||||
<el-icon class="text-[#999999]"><Plus /></el-icon>
|
<el-icon class="text-[#999999]"><Plus /></el-icon>
|
||||||
<div class="ml-4px mt-2px text-14px text-[#999999] font-normal">上传图纸</div>
|
<div class="ml-[4px] mt-[2px] text-[14px] text-[#999999] font-normal">上传图纸</div>
|
||||||
</div>
|
</div>
|
||||||
</KlUploader>
|
</KlUploader>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -72,7 +72,7 @@
|
|||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<el-input v-model="form.description" type="textarea" :rows="6" placeholder="请输入描述" class="w-361px!" minlength="70" show-word-limit></el-input>
|
<el-input v-model="form.description" type="textarea" :rows="6" placeholder="请输入描述" class="w-[361px]!" minlength="70" show-word-limit></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 添加预览和保存按钮 -->
|
<!-- 添加预览和保存按钮 -->
|
||||||
<el-form-item label-width="110px" label=" ">
|
<el-form-item label-width="110px" label=" ">
|
||||||
@ -92,6 +92,7 @@
|
|||||||
import { parent, keywords, labels } from '~/api/upnew/index'
|
import { parent, keywords, labels } from '~/api/upnew/index'
|
||||||
import { create } from '~/api/toolbox/index.js'
|
import { create } from '~/api/toolbox/index.js'
|
||||||
import type { TcreateReq } from '~/api/toolbox/types'
|
import type { TcreateReq } from '~/api/toolbox/types'
|
||||||
|
const router = useRouter() // 导入路由实例,用于跳转页面
|
||||||
|
|
||||||
const form = reactive<TcreateReq>({
|
const form = reactive<TcreateReq>({
|
||||||
title: '',
|
title: '',
|
||||||
@ -170,9 +171,10 @@
|
|||||||
console.log(res)
|
console.log(res)
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
ElMessage.success('发布成功')
|
ElMessage.success('发布成功')
|
||||||
window.setTimeout(() => {
|
router.back()
|
||||||
window.close()
|
// window.setTimeout(() => {
|
||||||
}, 1000)
|
// window.close()
|
||||||
|
// }, 1000)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<header class="h-90px">
|
<header class="h-[90px]">
|
||||||
<div class="mx-a h-full flex items-center justify-center">
|
<div class="mx-a h-full flex items-center justify-center">
|
||||||
<!-- 搜索区域 -->
|
<!-- 搜索区域 -->
|
||||||
<div class="relative w-647px px4 p-r-0px!">
|
<div class="relative 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 h40 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]"
|
||||||
@keyup.enter="search"
|
@keyup.enter="search"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -18,13 +18,13 @@
|
|||||||
<!-- 按钮区域 -->
|
<!-- 按钮区域 -->
|
||||||
<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]"
|
||||||
@click="search"
|
@click="search"
|
||||||
>
|
>
|
||||||
搜索
|
搜索
|
||||||
</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"
|
||||||
>
|
>
|
||||||
上传工具
|
上传工具
|
||||||
@ -37,7 +37,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { Search } from '@element-plus/icons-vue'
|
import { Search } from '@element-plus/icons-vue'
|
||||||
import useUserStore from '~/store/user'
|
import useUserStore from '~/stores/user'
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
|
||||||
const emits = defineEmits(['search'])
|
const emits = defineEmits(['search'])
|
||||||
|
|||||||
@ -2,47 +2,47 @@
|
|||||||
<KlNavTab active="工具箱" />
|
<KlNavTab active="工具箱" />
|
||||||
<!-- 搜索 -->
|
<!-- 搜索 -->
|
||||||
<KlSearch @search="search"></KlSearch>
|
<KlSearch @search="search"></KlSearch>
|
||||||
<div v-loading="loading" class="ml-auto mr-auto mt-20px w1440 flex justify-center gap-60px">
|
<div v-loading="loading" class="ma-auto mt-[20px] w-[1440px] flex justify-center gap-[60px]">
|
||||||
<div class="left w-821px">
|
<div class="left w-[821px]">
|
||||||
<img src="~/assets/images/banner2.png" alt="" srcset="" class="h-284px w-100%" />
|
<img src="~/assets/images/banner2.png" alt="" srcset="" class="h-[284px] w-[100%]" />
|
||||||
<div
|
<div
|
||||||
class="box-border border border-t-0px border-t-0px border-[#EEEEEE] rounded-12px border-solid border-t-none bg-[#FFFFFF] px-28px py-17px"
|
class="box-border border border-t-[0px] border-t-[0px] border-[#EEEEEE] rounded-[12px] border-solid border-t-none bg-[#FFFFFF] px-[28px] py-[17px]"
|
||||||
style="border-top-left-radius: 0px; border-top-right-radius: 0px"
|
style="border-top-left-radius: 0px; border-top-right-radius: 0px"
|
||||||
>
|
>
|
||||||
<div v-for="item in pageRes.list" :key="item.id" class="mt-20px flex border-b-1px border-b-[#eee] border-b-solid pb-20px">
|
<div v-for="item in pageRes?.list" :key="item.id" class="mt-[20px] flex border-b-[1px] border-b-[#eee] border-b-solid pb-[20px]">
|
||||||
<div class="h-142px w-200px text-center">
|
<div class="h-[142px] w-[200px] text-center">
|
||||||
<el-image :src="item.iconUrl" alt="" srcset="" class="max-w-100% rd-4px" fit="cover" />
|
<el-image :src="item.iconUrl" alt="" srcset="" class="max-w-[100%] rd-[4px]" fit="cover" />
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-25px flex-1">
|
<div class="ml-[25px] flex-1">
|
||||||
<div class="text-16px text-[#333333] font-normal">{{ item.title }}</div>
|
<div class="text-[16px] text-[#333333] font-normal">{{ item.title }}</div>
|
||||||
<div class="mt-8px text-14px text-[#999999] font-normal">{{ item.description }}</div>
|
<div class="mt-[8px] text-[14px] text-[#999999] font-normal">{{ item.description }}</div>
|
||||||
<div class="mt-10px flex items-center justify-between">
|
<div class="mt-[10px] flex items-center justify-between">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="flex items-center text-14px text-[#666666] font-normal">
|
<div class="flex items-center text-[14px] text-[#666666] font-normal">
|
||||||
<img src="~/assets/images/look.png" alt="" srcset="" class="mr-4px h-17px w-23px" />{{ item.previewPoint }}
|
<img src="~/assets/images/look.png" alt="" srcset="" class="mr-[4px] h-[17px] w-[23px]" />{{ item.previewPoint }}
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-26px flex items-center text-14px text-[#666666] font-normal">
|
<div class="ml-[26px] flex items-center text-[14px] text-[#666666] font-normal">
|
||||||
<img src="~/assets/images/chat.png" alt="" srcset="" class="mr-4px h-17px w-19px" /> {{ item.commentsPoint }}
|
<img src="~/assets/images/chat.png" alt="" srcset="" class="mr-[4px] h-[17px] w-[19px]" /> {{ item.commentsPoint }}
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-20px">
|
<div class="ml-[20px]">
|
||||||
<div v-for="(v, index) in item.labels" :key="index" class="mr-10px inline-block text-14px text-[#1A65FF] font-normal">#{{ v }}</div>
|
<div v-for="(v, index) in item.labels" :key="index" class="mr-[10px] inline-block text-[14px] text-[#1A65FF] font-normal">#{{ v }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-14px text-[#999999] font-normal">{{ dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss') }}</div>
|
<div class="text-[14px] text-[#999999] font-normal">{{ dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 暂无数据 -->
|
<!-- 暂无数据 -->
|
||||||
<div v-if="pageRes.list.length === 0" class="mt-10px flex items-center justify-center">
|
<div v-if="pageRes?.list.length === 0" class="mt-[10px] flex items-center justify-center">
|
||||||
<!-- <div class="text-16px text-[#999999] font-normal">暂无数据</div> -->
|
<!-- <div class="text-16px text-[#999999] font-normal">暂无数据</div> -->
|
||||||
<el-empty v-if="!pageRes.list.length" :image="emptyImg"></el-empty>
|
<el-empty v-if="!pageRes.list.length" :image="emptyImg"></el-empty>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-20px">
|
<div class="mt-[20px]">
|
||||||
<el-pagination
|
<el-pagination
|
||||||
v-model:current-page="pageReq.pageNum"
|
v-model:current-page="pageReq.pageNum"
|
||||||
:page-size="pageReq.pageSize"
|
:page-size="pageReq.pageSize"
|
||||||
layout="total, sizes, prev, pager, next"
|
layout="total, sizes, prev, pager, next"
|
||||||
:total="pageRes.total"
|
:total="pageRes?.total"
|
||||||
:page-sizes="[10, 20, 30]"
|
:page-sizes="[10, 20, 30]"
|
||||||
class="justify-center!"
|
class="justify-center!"
|
||||||
@current-change="handleCurrentChange"
|
@current-change="handleCurrentChange"
|
||||||
@ -51,13 +51,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="right w-398px">
|
<div class="right w-[398px]">
|
||||||
<div class="box-border border border-[#EEEEEE] rounded-10px border-solid bg-[#FFFFFF] pa-20px">
|
<div class="box-border border border-[#EEEEEE] rounded-[10px] border-solid bg-[#FFFFFF] pa-[20px]">
|
||||||
<div class="flex items-center text-16px text-[#333333] font-normal">
|
<div class="flex items-center text-[16px] text-[#333333] font-normal">
|
||||||
<div class="mr-14px h-24px w-4px rounded-1px bg-[#1A65FF]"></div>
|
<div class="mr-[14px] h-[24px] w-[4px] rounded-[1px] bg-[#1A65FF]"></div>
|
||||||
热门排行
|
热门排行
|
||||||
</div>
|
</div>
|
||||||
<div v-for="item in recommendList" :key="item.id" class="mt-20px text-14px text-[#666] font-normal">{{ item.title }}</div>
|
<div v-for="item in recommendList" :key="item.id" class="mt-[20px] text-[14px] text-[#666] font-normal">{{ item.title }}</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<!-- <div class="mt-20px box-border w-398px border border-[#EEEEEE] rounded-10px border-solid bg-[#FFFFFF] pa-20px">
|
<!-- <div class="mt-20px box-border w-398px border border-[#EEEEEE] rounded-10px border-solid bg-[#FFFFFF] pa-20px">
|
||||||
@ -110,26 +110,31 @@
|
|||||||
title: '',
|
title: '',
|
||||||
})
|
})
|
||||||
|
|
||||||
const pageRes = ref<TpageRes>({
|
// const pageRes = ref<TpageRes>({
|
||||||
list: [],
|
// list: [],
|
||||||
total: 0,
|
// total: 0,
|
||||||
|
// })
|
||||||
|
|
||||||
|
const {data: pageRes, refresh: getPage } = await useAsyncData(`draw-page-list-${Date.now()}`, async () => {
|
||||||
|
const res = await page(pageReq)
|
||||||
|
return res.data
|
||||||
})
|
})
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const getPage = () => {
|
// const getPage = () => {
|
||||||
loading.value = true
|
// loading.value = true
|
||||||
page(pageReq)
|
// page(pageReq)
|
||||||
.then((res) => {
|
// .then((res) => {
|
||||||
if (res.code === 0) {
|
// if (res.code === 0) {
|
||||||
pageRes.value = res.data
|
// pageRes.value = res.data
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
.finally(() => {
|
// .finally(() => {
|
||||||
loading.value = false
|
// loading.value = false
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
getPage()
|
// getPage()
|
||||||
|
|
||||||
const handleCurrentChange = (page: number) => {
|
const handleCurrentChange = (page: number) => {
|
||||||
pageReq.pageNum = page
|
pageReq.pageNum = page
|
||||||
@ -148,17 +153,24 @@
|
|||||||
getPage()
|
getPage()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 猜你喜欢
|
const {data: recommendList} = await useAsyncData(`draw-recommend-list-${Date.now()}`, async () => {
|
||||||
const recommendList = ref<ProjectDrawPageRespVO[]>([]) // 猜你喜欢数据
|
const res = await getRelationRecommend({
|
||||||
const getRelationRecommendList = () => {
|
|
||||||
getRelationRecommend({
|
|
||||||
type: 4,
|
type: 4,
|
||||||
}).then((res) => {
|
|
||||||
if (res.code === 0) {
|
|
||||||
console.log(res.data)
|
|
||||||
recommendList.value = res.data
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
return res.data
|
||||||
getRelationRecommendList()
|
})
|
||||||
|
|
||||||
|
// 猜你喜欢
|
||||||
|
// const recommendList = ref<ProjectDrawPageRespVO[]>([]) // 猜你喜欢数据
|
||||||
|
// const getRelationRecommendList = () => {
|
||||||
|
// getRelationRecommend({
|
||||||
|
// type: 4,
|
||||||
|
// }).then((res) => {
|
||||||
|
// if (res.code === 0) {
|
||||||
|
// console.log(res.data)
|
||||||
|
// recommendList.value = res.data
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// getRelationRecommendList()
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,24 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="ml-23px box-border min-h-930px w-516px border border-[#EEEEEE] rounded-12px border-solid bg-[#FFFFFF] px-33px py-22px">
|
<div class="ml-[23px] box-border min-h-[930px] w-[516px] border border-[#EEEEEE] rounded-[12px] border-solid bg-[#FFFFFF] px-[33px] py-[22px]">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<img src="~/assets/images/preview.png" alt="" srcset="" width="16px" height="19px" /><span class="ml-7px text-18px text-[#333333] font-normal"
|
<img src="~/assets/images/preview.png" alt="" srcset="" width="16px" height="19px" /><span class="ml-[7px] text-[18px] text-[#333333] font-normal"
|
||||||
>预览</span
|
>预览</span
|
||||||
></div
|
></div
|
||||||
>
|
>
|
||||||
<div class="mt-20px">
|
<div class="mt-[20px]">
|
||||||
<el-image :src="previewUrl" class="mb-16px max-h-320px max-w-460px min-h-200px" fit="contain"></el-image>
|
<el-image :src="previewUrl" class="mb-[16px] max-h-[320px] max-w-[460px] min-h-[200px]" fit="contain"></el-image>
|
||||||
<span class="text-16px text-[#333333] font-normal">{{ previewName || '图纸标题' }}</span></div
|
<span class="text-[16px] text-[#333333] font-normal">{{ previewName || '图纸标题' }}</span></div
|
||||||
>
|
>
|
||||||
<div class="my-30px h-1px w-460px rounded-1px bg-[#EEEEEE]"></div>
|
<div class="my-[30px] h-[1px] w-[460px] rounded-[1px] bg-[#EEEEEE]"></div>
|
||||||
<div class="flex items-center"
|
<div class="flex items-center">
|
||||||
><img src="~/assets/images/tip.png" width="20px" height="20px" /><span class="ml-7px text-18px text-[#333333] font-normal"
|
<img src="~/assets/images/tip.png" width="20px" height="20px" />
|
||||||
>上传遇到问题可以咨询</span
|
<span class="ml-[7px] text-[18px] text-[#333333] font-normal">
|
||||||
></div
|
上传遇到问题可以咨询
|
||||||
>
|
</span>
|
||||||
<div class="mt-20px text-center"><el-image src="https://picsum.photos/290/290?_t" alt="" srcset="" class="h-290px w290" /></div>
|
</div>
|
||||||
<div class="mt-30px text-center text-16px text-[#333333] font-normal">
|
<div class="mt-[20px] text-center"><el-image src="https://picsum.photos/290/290?_t" alt="" srcset="" class="h-[290px] w-[290px]" /></div>
|
||||||
|
<div class="mt-[30px] text-center text-[16px] text-[#333333] font-normal">
|
||||||
<div>TEL:13315189735 </div>
|
<div>TEL:13315189735 </div>
|
||||||
<div class="mt-4px">在线时间:8:30-18:00</div>
|
<div class="mt-[4px]">在线时间:8:30-18:00</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user