Commit 6a3cf54d by lijiabin

【需求 17679】 feat: 继续优化页面、调试企微API、优化搜索页面等

parent 890412b9
......@@ -24,6 +24,7 @@
"@element-plus/icons-vue": "^2.3.2",
"@vueuse/components": "^14.0.0",
"@vueuse/core": "^14.0.0",
"@wecom/jssdk": "^2.3.3",
"archiver": "^7.0.1",
"axios": "^1.13.0",
"dayjs": "^1.11.19",
......
......@@ -17,6 +17,9 @@ importers:
'@vueuse/core':
specifier: ^14.0.0
version: 14.0.0(vue@3.5.22(typescript@5.9.3))
'@wecom/jssdk':
specifier: ^2.3.3
version: 2.3.3
archiver:
specifier: ^7.0.1
version: 7.0.1
......@@ -89,7 +92,7 @@ importers:
version: 5.9.3
unocss:
specifier: ^66.5.4
version: 66.5.4(postcss@5.2.18)(vite@7.1.12(@types/node@22.18.12)(jiti@2.6.1)(sass-embedded@1.93.2)(sass@1.93.2))
version: 66.5.4(postcss@8.5.6)(vite@7.1.12(@types/node@22.18.12)(jiti@2.6.1)(sass-embedded@1.93.2)(sass@1.93.2))
unplugin-auto-import:
specifier: ^20.2.0
version: 20.2.0(@vueuse/core@14.0.0(vue@3.5.22(typescript@5.9.3)))
......@@ -1080,6 +1083,9 @@ packages:
'@vueuse/shared@9.13.0':
resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==}
'@wecom/jssdk@2.3.3':
resolution: {integrity: sha512-bazYSD39MoiaUV1xMVxrOPsTFa37ARY0xXAqDgth4kU/xk8n61o1YiAcdn4dPM+kBnJKOfukFYPjOPQv8K5l+w==}
abort-controller@3.0.0:
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
engines: {node: '>=6.5'}
......@@ -4253,13 +4259,13 @@ snapshots:
sirv: 3.0.2
vue-flow-layout: 0.2.0
'@unocss/postcss@66.5.4(postcss@5.2.18)':
'@unocss/postcss@66.5.4(postcss@8.5.6)':
dependencies:
'@unocss/config': 66.5.4
'@unocss/core': 66.5.4
'@unocss/rule-utils': 66.5.4
css-tree: 3.1.0
postcss: 5.2.18
postcss: 8.5.6
tinyglobby: 0.2.15
'@unocss/preset-attributify@66.5.4':
......@@ -4594,6 +4600,8 @@ snapshots:
- '@vue/composition-api'
- vue
'@wecom/jssdk@2.3.3': {}
abort-controller@3.0.0:
dependencies:
event-target-shim: 5.0.1
......@@ -6973,12 +6981,12 @@ snapshots:
universalify@2.0.1: {}
unocss@66.5.4(postcss@5.2.18)(vite@7.1.12(@types/node@22.18.12)(jiti@2.6.1)(sass-embedded@1.93.2)(sass@1.93.2)):
unocss@66.5.4(postcss@8.5.6)(vite@7.1.12(@types/node@22.18.12)(jiti@2.6.1)(sass-embedded@1.93.2)(sass@1.93.2)):
dependencies:
'@unocss/astro': 66.5.4(vite@7.1.12(@types/node@22.18.12)(jiti@2.6.1)(sass-embedded@1.93.2)(sass@1.93.2))
'@unocss/cli': 66.5.4
'@unocss/core': 66.5.4
'@unocss/postcss': 66.5.4(postcss@5.2.18)
'@unocss/postcss': 66.5.4(postcss@8.5.6)
'@unocss/preset-attributify': 66.5.4
'@unocss/preset-icons': 66.5.4
'@unocss/preset-mini': 66.5.4
......
......@@ -7,16 +7,16 @@
</template>
<script setup lang="ts">
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import { useUserStore } from '@/stores/user'
import { initWxConfig } from '@/utils/wxUtil/initWXConfig'
const locale = ref(zhCn)
// const userStore = useUserStore()
// userStore.fetchUserInfo().then((res) => {
// console.log(res)
// })
console.log('App.vue mounted')
onMounted(() => {
const userStore = useUserStore()
alert('token' + userStore.token)
setTimeout(() => {
initWxConfig()
}, 3000);
})
</script>
......@@ -137,7 +137,7 @@
</div>
</div>
<!-- 回复列表 -->
<div v-if="item.children.length" class="mt-3 ml-4 space-y-3">
<div v-if="item.children?.length" class="mt-3 ml-4 space-y-3">
<div
v-for="child in item.children"
:key="child.id"
......@@ -311,7 +311,7 @@ const handleReply = (item: CommentItemDto) => {
}
const showCommentBox = (item: CommentItemDto) => {
return (
currentCommentId.value === item.id || item.children.some((i) => i.id === currentCommentId.value)
currentCommentId.value === item.id || item.children?.some((i) => i.id === currentCommentId.value)
)
}
......
......@@ -24,8 +24,8 @@ export const app_config: { [key: string]: IConfig } = {
// 开发环境
development: {
// baseUrl: 'http://192.168.2.110:8082', // 线上测试机
baseUrl: 'http://192.168.2.168:8089', // 立鹏本地
baseUrl: 'http://culture.yswg.com.cn:8089', // 线上测试机
// baseUrl: 'http://192.168.2.168:8089', // 立鹏本地/
// baseUrl: 'http://192.168.2.55:8089', // 首拥本地
loginType: 1,
// wxRedirect: 'oatest.yswg.com.cn:3457',
......
<template>
<div class="layout-culture pb-11 h-full bg-[linear-gradient(to_bottom,#F0FBFD_0%,#ECEFFF_100%)]">
<div
class="header flex px-40 items-center justify-between bg-white mb-1 shadow-sm fixed top-0 left-0 right-0 z-100 w-100vw"
>
class="header flex px-40 items-center justify-between bg-white mb-1 shadow-sm fixed top-0 left-0 right-0 z-100 w-100vw">
<!-- Logo区域 -->
<div @click="router.push('/')" class="flex items-center flex-shrink-0 min-w-0 cursor-pointer">
<img
class="h-10 mr-3 object-contain flex-shrink-0 sm:h-10 sm:mr-4"
src="http://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/2022/10/13/1665643779583.png"
alt=""
/>
<img class="h-10 mr-3 object-contain flex-shrink-0 sm:h-10 sm:mr-4"
src="http://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/2022/10/13/1665643779583.png" alt="" />
</div>
<div class="flex items-center">
<!-- 搜索框 -->
<div class="flex-1 max-w-sm mx-4 hidden md:block lg:max-w-md lg:mx-6">
<div v-show="showSearchInupt" class="flex-1 max-w-sm mx-4 hidden md:block lg:max-w-md lg:mx-6">
<el-input v-model="search" class="h-8" placeholder="搜索">
<template #suffix>
<el-icon class="text-gray-400" @click="router.push('/searchPage')">
<el-icon class="text-gray-400" @click="router.push('/searchPage?title=' + search)">
<Search />
</el-icon>
</template>
......@@ -27,44 +23,20 @@
<div class="flex items-center gap-1 flex-shrink-0 sm:gap-2 lg:gap-4">
<div
class="flex items-center cursor-pointer px-2 py-1 rounded transition-colors sm:px-3 sm:py-2 hover:shadow-lg duration-200"
@click="router.push('/userPage')"
>
<img
class="w-8 h-8 object-contain flex-shrink-0 rounded-full"
:src="userInfo?.avatar"
alt="个人中心"
/>
<span class="ml-2 text-sm text-gray-700 whitespace-nowrap hidden lg:inline"
>个人中心</span
>
@click="router.push('/userPage')">
<img class="w-8 h-8 object-contain flex-shrink-0 rounded-full" :src="userInfo?.avatar" alt="个人中心" />
<span class="ml-2 text-sm text-gray-700 whitespace-nowrap hidden lg:inline">个人中心</span>
</div>
<div
class="flex items-center cursor-pointer px-2 py-1 rounded sm:px-3 sm:py-2 hover:shadow-lg duration-200"
>
<img
class="w-7 h-7 object-contain flex-shrink-0"
src="@/assets/img/culture/feedback.png"
alt=""
/>
<span class="ml-2 text-sm text-gray-700 whitespace-nowrap hidden lg:inline"
>意见反馈</span
>
<div class="flex items-center cursor-pointer px-2 py-1 rounded sm:px-3 sm:py-2 hover:shadow-lg duration-200">
<img class="w-7 h-7 object-contain flex-shrink-0" src="@/assets/img/culture/feedback.png" alt="" />
<span class="ml-2 text-sm text-gray-700 whitespace-nowrap hidden lg:inline">意见反馈</span>
</div>
<el-dropdown
placement="top-start"
@command="handlePost"
@visible-change="(val) => (isDropdownHover = val)"
>
<el-dropdown placement="top-start" @command="handlePost" @visible-change="(val) => (isDropdownHover = val)">
<button
class="cursor-pointer w-24 h-9 text-black hover:text-black bg-[linear-gradient(to_right,#B3B8FD_0%,#7083FF_100%)] border-none duration-200 flex-1 text-xs sm:text-sm rounded-xl group"
:class="{ 'shadow-[0_1px_8px_0_rgba(95,0,237,0.25)]': isDropdownHover }"
>
<img
class="h-7 w-7 transition-transform duration-300 ease-in-out"
:class="{ 'rotate-90': isDropdownHover }"
src="@/assets/img/culture/post.png"
alt=""
/>
:class="{ 'shadow-[0_1px_8px_0_rgba(95,0,237,0.25)]': isDropdownHover }">
<img class="h-7 w-7 transition-transform duration-300 ease-in-out"
:class="{ 'rotate-90': isDropdownHover }" src="@/assets/img/culture/post.png" alt="" />
去发帖
</button>
<template #dropdown>
......@@ -80,9 +52,7 @@
</div>
</div>
<div class="flex-1 w-full flex items-center justify-center">
<div
class="container max-h-none px-20 lg:px-20 2xl:px-30 transition-all duration-300 min-h-[calc(100vh-96px)]"
>
<div class="container max-h-none px-20 lg:px-20 2xl:px-30 transition-all duration-300 min-h-[calc(100vh-96px)]">
<router-view v-slot="{ Component, route }">
<transition name="fade" mode="out-in">
<!-- 注释不能放到keep-alive下面 route是最终的路由信息 Component是当前n级路由的组件 二级路由 homePage videoDetail -->
......@@ -112,9 +82,11 @@ const userStore = useUserStore()
const { userInfo } = storeToRefs(userStore)
const router = useRouter()
const route = useRoute()
const search = ref('')
const PublishDialogRef = useTemplateRef<InstanceType<typeof PublishDialog>>('PublishDialogRef')
console.log(route)
const showSearchInupt = computed(() => route.path !== '/searchPage')
// 获取二级路由的 key
const getSecondLevelKey = (route: RouteLocationNormalizedLoadedGeneric) => {
// 取第一级作为key homePage
......@@ -137,6 +109,7 @@ const isDropdownHover = ref(false)
<style lang="scss" scoped>
.layout-culture {
padding-top: 52px;
.header {
min-height: 52px;
color: #212121;
......@@ -145,11 +118,13 @@ const isDropdownHover = ref(false)
background-size: 100% 100%;
background-repeat: no-repeat;
}
.container {
.main-container {
.tabs-container {
background: linear-gradient(90deg, #16cdea 0%, #d680ff 100%);
}
.right {
.common-box {
padding: 15px;
......@@ -157,6 +132,7 @@ const isDropdownHover = ref(false)
border-radius: 10px;
border: 1px solid #efe7dc;
}
.common-btn {
display: flex;
align-items: center;
......@@ -178,6 +154,7 @@ const isDropdownHover = ref(false)
opacity: 0;
transform: translateY(10px);
}
.fade-enter-active,
.fade-leave-active {
transition: all 0.3s ease;
......
......@@ -54,9 +54,6 @@ export default class DhRequest {
}
return response.data
} else {
if (response.status === 401) {
alert(JSON.stringify(response))
}
// 处理请求成功后错误
return handleResponseError(response)
}
......
......@@ -71,9 +71,6 @@ export function handleRequestError(axiosError: AxiosError<BackendServiceResult>)
// 请求出错,如404, 403
else {
const errorCode: ErrorStatus = axiosError.response?.status as ErrorStatus
if (errorCode === 401) {
alert(JSON.stringify(axiosError))
}
const msg =
axiosError.response?.data.message || ERROR_STATUS[errorCode] || DEFAULT_REQUEST_ERROR_MSG
Object.assign(error, { code: errorCode || DEFAULT_REQUEST_ERROR_CODE, msg })
......
export * from './wxLogin'
export * from './initWXConfig'
// import wx from 'weixin-js-sdk'
import * as ww from '@wecom/jssdk'
/**
* 分享
......@@ -16,13 +15,22 @@ interface IShareWxOption {
/** 分享封面 */
imgUrl?: string
}
// export function wxShare(option: IShareWxOption) {
// const url = location.href.split('#')[0]
// option.link = url + '#' + option.link
// wx.invoke('shareAppMessage', option, function (res: any) {
// if (res.err_msg == 'openExistedChatWithMsg:ok') {
// console.log(res)
// }
// })
// }
export function wxShare(option: IShareWxOption) {
const url = location.href.split('#')[0]
option.link = url + '#' + option.link
wx.invoke('shareAppMessage', option, function (res: any) {
if (res.err_msg == 'openExistedChatWithMsg:ok') {
console.log(res)
}
option.link = ww.shareAppMessage({
title: '测试一下',
desc: '让每个企业都有自己的微信',
link: url + '#' + option.link,
imgUrl: 'https://res.mail.qq.com/node/ww/wwmng/style/images/index_share_logo$13c64306.png',
})
}
......
/* 企业微信js配置 */
//注意:如果要在页面调用企业微信内部方法,请现在下面的jsApiList数组中添加方法
import { getWxSignature } from '@/api'
// import wx from 'weixin-js-sdk'
import * as ww from '@wecom/jssdk'
// export async function initWxConfig() {
// const url = location.href.split('#')[0]
// const response = await getWxSignature(url)
// console.log('response', response, wx)
// const timestamp = response.data.timestamp //时间戳
// const nonceStr = response.data.nonceStr //随机字符串
// const signature = response.data.signature //签名
// const appId = response.data.appId //企业id
// wx.config({
// beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题
// debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
// appId: appId, // 必填,企业微信的corpID
// timestamp: timestamp, // 必填,生成签名的时间戳
// nonceStr: nonceStr, // 必填,生成签名的随机串
// signature: signature, // 必填,签名,见附录1
// jsApiList: [
// // 所有要调用的 API 都要加到这个列表中
// 'shareAppMessage',
// 'selectEnterpriseContact',
// ],
// // success: function (result) {
// // // 回调
// // }
// })
// }
export async function initWxConfig() {
const url = location.href.split('#')[0]
const response = await getWxSignature(url)
......@@ -10,21 +36,26 @@ export async function initWxConfig() {
const timestamp = response.data.timestamp //时间戳
const nonceStr = response.data.nonceStr //随机字符串
const signature = response.data.signature //签名
const appId = response.data.appId //企业id
wx.config({
beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: appId, // 必填,企业微信的corpID
timestamp: timestamp, // 必填,生成签名的时间戳
nonceStr: nonceStr, // 必填,生成签名的随机串
signature: signature, // 必填,签名,见附录1
jsApiList: [
// 所有要调用的 API 都要加到这个列表中
'shareAppMessage',
'selectEnterpriseContact',
],
// success: function (result) {
// // 回调
// }
// const appId = response.data.appId //企业id
const corpId = response.data.corpid //企业id
const agentId = response.data.agentid //应用id
ww.register({
corpId, // 必填,当前用户企业所属企业ID
agentId, // 必填,当前应用的AgentID
jsApiList: ['shareAppMessage'], // 必填,需要使用的JSAPI列表
getConfigSignature: function () {
return {
timestamp: timestamp,
nonceStr: nonceStr,
signature: signature,
}
}, // 必填,根据url生成企业签名的回调函数
getAgentConfigSignature: function () {
return {
timestamp: timestamp,
nonceStr: nonceStr,
signature: signature,
}
}, // 必填,根据url生成应用签名的回调函数
})
}
......@@ -11,19 +11,13 @@
<div class="flex gap-3">
<div class="left flex-1 basis-full xl:basis-3/4 transition-all duration-500">
<div ref="tabsRef" class="tabs-container h-75px flex relative rounded-lg mb-3 shadow-md">
<div
v-for="tab in tabs"
:key="tab.path"
<div v-for="tab in tabs" :key="tab.path"
class="flex-1 flex items-center justify-center cursor-pointer relative transition-all duration-300 group"
@click="toggleTab(tab)"
>
<div
class="flex items-center gap-2 px-12 py-2.5 rounded-lg transition-all duration-300"
:class="{
@click="toggleTab(tab)">
<div class="flex items-center gap-2 px-12 py-2.5 rounded-lg transition-all duration-300" :class="{
'bg-#fffdfd shadow-[inset_0_2px_4px_0_rgb(0,0,0,0.1)]': activeTab === tab.name,
'hover:bg-white/60': activeTab !== tab.name,
}"
>
}">
<svg-icon :name="tab.svg" class="h-60px w-auto md:h-50px sm:h-40px" size="40" />
<div class="text-18px font-500 text-gray-800 md:text-16px sm:text-14px">
{{ tab.name }}
......@@ -33,8 +27,7 @@
</div>
<div
class="content-container w-100% rounded-lg bg-#F5F8FD border-1px border-solid border-#EAEAEF shadow-[0_1px_4px_0_rgba(33,33,52,0.1)]"
>
class="content-container w-100% rounded-lg bg-#F5F8FD border-1px border-solid border-#EAEAEF shadow-[0_1px_4px_0_rgba(33,33,52,0.1)]">
<div class="content-wrapper p-6">
<router-view v-slot="{ Component, route }">
<transition name="fade" mode="out-in">
......@@ -49,10 +42,8 @@
<!-- 屏幕变小直接隐藏 -->
<div class="right flex-col gap-3 xl:flex xl:basis-1/4 hidden">
<!-- 等级等相关信息 -->
<div
ref="levelContainerRef"
class="level-container common-box flex flex-col justify-center items-center gap-4 rounded-lg bg-#E4F5FE"
>
<div ref="levelContainerRef"
class="level-container common-box flex flex-col justify-center items-center gap-4 rounded-lg bg-#E4F5FE">
<div class="top flex items-center justify-center gap-3">
<img class="h-20" :src="currentLevelData?.iconUrl" alt="" />
<div class="text-base flex-3/4 flex flex-col gap-1">
......@@ -60,20 +51,16 @@
<div class="font-semibold">等级:{{ currentLevelData?.label }}</div>
<el-tooltip
:content="`当前经验:${userAccountData.expTotal}/${currentLevelData.expScope[1]} (${currentLevelData.percentage}%)`"
placement="top"
>
placement="top">
<div class="relative w-20 cursor-pointer">
<div
class="relative w-full h-4 bg-#A5E4FF rounded-full border-1 border-#30C4FF border-solid"
>
<div class="relative w-full h-4 bg-#A5E4FF rounded-full border-1 border-#30C4FF border-solid">
<div class="absolute left-0 top-0 h-full bg-#30C4FF rounded-full"></div>
<div
class="absolute left-0 top-0 h-full bg-gradient-to-r from-blue-500 via-blue-400 to-cyan-400 rounded-full transition-all duration-500 ease-out"
:style="{ width: `${currentLevelData.percentage}%` }"
>
:style="{ width: `${currentLevelData.percentage}%` }">
<div
class="absolute top-0 left-0 w-full h-1/2 bg-gradient-to-b from-white/40 to-transparent rounded-t-full"
></div>
class="absolute top-0 left-0 w-full h-1/2 bg-gradient-to-b from-white/40 to-transparent rounded-t-full">
</div>
</div>
</div>
</div>
......@@ -88,10 +75,7 @@
<div ref="dailySignBtnRef">
<el-button
class="bg-[linear-gradient(to_right,#FFD06A_0%,#FFB143_100%)] shadow-[0px_1px_8px_0_rgba(255,173,91,0.25)] border-none hover:-translate-y-1 hover:shadow-[0px_4px_10px_0_rgba(255,173,91,0.4)] hover:scale-105 active:scale-95 active:translate-y-0 transition-all duration-200 flex-1 text-xs sm:text-sm"
type="primary"
@click="onDailySign"
v-if="!userRecordData.isSign"
>
type="primary" @click="onDailySign" v-if="!userRecordData.isSign">
<!-- v-if="!userRecordData.isSign" -->
<svg-icon name="sign_in" size="35" />
......@@ -100,9 +84,7 @@
</div>
<el-button
class="bg-[linear-gradient(to_right,#ABB0FF_0%,#7495FF_100%)] shadow-[0_1px_8px_0_rgba(0,36,237,0.25)] border-none hover:-translate-y-1 transition-all duration-200 flex-1 text-xs sm:text-sm w-116px"
type="primary"
@click="router.push('/pointsStore')"
>
type="primary" @click="router.push('/pointsStore')">
<svg-icon name="points_store" size="30" />
<span class="text-black text-xs sm:text-sm">积分商城</span>
</el-button>
......@@ -121,9 +103,7 @@
<div class="flex justify-center items-center">
<el-button
class="bg-[linear-gradient(to_right,#A3EADC_0%,#7BE0BD_100%)] shadow-[0_1px_4px_0_rgba(168,225,210,1)] border-none hover:-translate-y-1 transition-all duration-200 text-xs sm:text-sm w-116px"
type="primary"
@click="router.push('/publishCase')"
>
type="primary" @click="router.push('/publishCase')">
<svg-icon name="submit" size="20" class="mr-2" />
<span class="text-black text-xs sm:text-sm">去投稿</span>
</el-button>
......@@ -134,29 +114,26 @@
<div class="grid grid-cols-3 gap-2 sm:gap-4 mb-4">
<div
class="flex flex-col items-center justify-center text-center cursor-pointer hover:-translate-y-1 transition-transform duration-200 p-2 rounded-lg hover:bg-white/10"
>
@click="router.push('/homePage/askTab')">
<svg-icon name="topic_release" size="80" />
<div class="text-xs sm:text-sm">话题发布</div>
</div>
<div
class="flex flex-col items-center justify-center text-center cursor-pointer hover:-translate-y-1 transition-transform duration-200 p-2 rounded-lg hover:bg-white/10"
>
@click="router.push('/homePage/askTab')">
<svg-icon name="answer" size="80" />
<div class="text-xs sm:text-sm">回答问题</div>
</div>
<div
@click="router.push('/publishVideo')"
class="flex flex-col items-center justify-center text-center cursor-pointer hover:-translate-y-1 transition-transform duration-200 p-2 rounded-lg hover:bg-white/10"
>
<div @click="router.push('/publishVideo')"
class="flex flex-col items-center justify-center text-center cursor-pointer hover:-translate-y-1 transition-transform duration-200 p-2 rounded-lg hover:bg-white/10">
<svg-icon name="video_release" size="80" />
<div class="text-xs sm:text-sm">视频发布</div>
</div>
</div>
<div class="flex justify-center items-center">
<el-button
<el-button @click="router.push('/homePage/askTab')"
class="bg-[linear-gradient(to_right,#D6C9FF_0%,#C5B1FF_100%)] shadow-[0_1px_4px_0_rgba(95,0,237,0.25)] border-none hover:-translate-y-1 transition-all duration-200 text-xs sm:text-sm w-116px"
type="primary"
>
type="primary">
<svg-icon name="my_answer" size="20" class="mr-2" />
<span class="text-black text-xs sm:text-sm">我的回答</span>
</el-button>
......@@ -171,17 +148,12 @@
<div class="w-1 h-4 bg-gradient-to-b from-pink-500 to-rose-500 rounded-full"></div>
<h1 class="text-sm sm:text-base font-bold">任务中心</h1>
</div>
<h2
class="w-full text-xs sm:text-sm mt-1 text-gray-600 flex items-center justify-between"
>
<h2 class="w-full text-xs sm:text-sm mt-1 text-gray-600 flex items-center justify-between">
<div>
<span
v-for="item in taskTypeList"
:key="item.value"
<span v-for="item in taskTypeList" :key="item.value"
class="text-#333 cursor-pointer after:content-['|'] after:mx-2 after:text-#999 last:after:content-none"
:class="{ 'text-#999': currentTask !== item.value }"
@click="currentTask = item.value"
>{{ item.label }}
:class="{ 'text-#999': currentTask !== item.value }" @click="currentTask = item.value">{{ item.label
}}
</span>
</div>
<span class="text-#999 cursor-pointer" @click="router.push(`/userPage?key=task`)">
......@@ -195,15 +167,12 @@
<div v-show="currentTaskList.length">
<div v-for="item in currentTaskList" :key="item.id">
<div
class="flex items-center justify-between hover:bg-white/10 rounded-lg transition-colors duration-200 group"
>
class="flex items-center justify-between hover:bg-white/10 rounded-lg transition-colors duration-200 group">
<div class="flex items-center min-w-0 flex-1">
<div class="h-70px flex items-center justify-center">
<svg-icon :name="item.svgName" size="50" />
</div>
<div
class="flex flex-col items-start justify-center ml-2 sm:ml-3 min-w-0 flex-1"
>
<div class="flex flex-col items-start justify-center ml-2 sm:ml-3 min-w-0 flex-1">
<el-tooltip :content="item.description" placement="top">
<div class="text-14px truncate w-full font-medium mb-1 cursor-pointer">
{{ item.title }}({{ item.currentCount }}/{{ item.limitCount }})
......@@ -227,16 +196,10 @@
item.currentCount === item.limitCount
? 'bg-#FFC5A1'
: 'bg-[linear-gradient(to_right,#FFC5A1_0%,#FFB77F_100%)] hover:-translate-y-1 transition-all duration-200 cursor-pointer',
]"
@click="handleTask(item)"
>
<span
class="text-black text-sm"
:style="{
]" @click="handleTask(item)">
<span class="text-black text-sm" :style="{
color: item.currentCount === item.limitCount ? '#999' : '#000',
}"
>{{ item.currentCount === item.limitCount ? '已完成' : '去完成' }}</span
>
}">{{ item.currentCount === item.limitCount ? '已完成' : '去完成' }}</span>
</button>
</div>
<!-- 分割线 -->
......@@ -366,19 +329,26 @@ const onDailySign = async () => {
const handleTask = (item: TaskItemDto) => {
console.log(item)
if (item.currentCount === item.limitCount) return
if (item.svgName === 'VALID_COMMENT1') {
router.push(`/homePage/homeTab`)
} else if (item.svgName === 'daily_sign') {
handleBackTop()
triggerAnimation()
} else {
console.log(item)
// if (item.svgName === 'svgName') {
// 先暂时写死
if (item.svgName === 'daily_sign') {
//每日签到
handleBackTop()
triggerAnimation()
} else if (item.svgName === 'valid_comments') {
// 发布评论
ElMessage.info('快去文章评论区去发表评论吧~')
} else if (item.svgName === 'topic_publish') {
router.push('/homePage/askTab')
} else if (item.svgName === 'answer_ask') {
// 回答问题
router.push('/homePage/askTab')
} else if (item.svgName === 'video_publish') {
// 视频发布
router.push('/publishVideo')
} else if (item.svgName === 'practice_publish') {
// 个人实践/投稿
router.push('/publishCase')
}
// }
}
const initPage = () => {
......@@ -423,16 +393,20 @@ provide(TABS_REF_KEY, tabsRef)
height: 100% !important;
}
}
padding-bottom: 100px;
.tabs-container {
background: linear-gradient(to right, #d1f3ff 0%, #bebeff 100%);
}
.right {
.common-box {
padding: 15px;
border: 1px solid #eaeaef;
box-shadow: 0 1px 4px 0 rgba(33, 33, 52, 0.1);
}
.common-btn {
display: flex;
align-items: center;
......@@ -451,11 +425,13 @@ provide(TABS_REF_KEY, tabsRef)
opacity: 0;
transform: translateY(10px);
}
.fade-enter-to,
.fade-leave-from {
opacity: 1;
transform: translateY(0);
}
.fade-enter-active,
.fade-leave-active {
transition: all 0.3s ease;
......
......@@ -2,42 +2,33 @@
<div>
<div v-loading="loading" v-if="list.length">
<div class="w-full max-w-6xl mx-auto">
<div
v-for="(item, index) in list"
:key="index"
class="bg-white rounded-lg shadow-sm mb-6 overflow-hidden"
:style="{ '--dynamic-color': item.color }"
>
<div
class="flex items-center justify-between pr-4 pl-4 pt-2 pb-2 bg-green-50 border-b border-green-100"
:style="{ backgroundColor: item.color, '--dynamic-color': item.color }"
>
<div v-for="(item, index) in list" :key="index" class="bg-white rounded-lg shadow-sm mb-6 overflow-hidden"
:style="{ '--dynamic-color': item.color }">
<div class="flex items-center justify-between pr-4 pl-4 pt-2 pb-2 bg-green-50 border-b border-green-100"
:style="{ backgroundColor: item.color, '--dynamic-color': item.color }">
<h3 class="text-lg font-medium text-gray-800 flex items-center">
<span class="w-1 h-5 mr-2 bg-#444"></span>
{{ item.title }}
</h3>
<div class="flex items-center cursor-pointer">
<div class="flex items-center cursor-pointer" @click="router.push({
path: '/searchPage',
query: {
type: ArticleTypeEnum.COLUMN
}
})">
<span class="mr-1 text-14px color-#606266">查看更多 >></span>
</div>
</div>
<div class="p-4">
<div v-if="item.yaColumnVoList.length" class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div
v-for="i in item.yaColumnVoList"
:key="i.articleId"
class="group cursor-pointer"
@click="router.push(`/articleDetail/${i.articleId}`)"
>
<div v-for="i in item.yaColumnVoList" :key="i.articleId" class="group cursor-pointer"
@click="router.push(`/articleDetail/${i.articleId}`)">
<div class="relative mb-3 overflow-hidden rounded-lg">
<img
:src="i.faceUrl"
class="w-full aspect-[5/3] object-cover group-hover:scale-105 transition-transform duration-300"
/>
<div
v-if="i.isRecommend"
class="absolute top--1 left--1 w-15 h-7 z-1000 bg-#FFF9B9 flex items-center justify-center border-2px border-solid border-#f4f0eb rounded-tl-lg rounded-br-lg"
>
<img :src="i.faceUrl"
class="w-full aspect-[5/3] object-cover group-hover:scale-105 transition-transform duration-300" />
<div v-if="i.isRecommend"
class="absolute top--1 left--1 w-15 h-7 z-1000 bg-#FFF9B9 flex items-center justify-center border-2px border-solid border-#f4f0eb rounded-tl-lg rounded-br-lg">
<img class="w-6" src="@/assets/img/culture/recommend.png" alt="" />
<div class="text-12px text-#000 line-height-12px">推荐</div>
</div>
......@@ -51,15 +42,21 @@
<div class="flex items-center justify-between text-xs text-gray-500">
<div class="flex items-center space-x-4">
<span class="flex items-center">
<el-icon class="mr-1"><View /></el-icon>
<el-icon class="mr-1">
<View />
</el-icon>
{{ i.viewCount }}
</span>
<span class="flex items-center">
<el-icon class="mr-1"><ChatDotRound /></el-icon>
<el-icon class="mr-1">
<ChatDotRound />
</el-icon>
{{ i.replyCount }}
</span>
<span class="flex items-center">
<el-icon class="mr-1"><Star /></el-icon>
<el-icon class="mr-1">
<Star />
</el-icon>
{{ i.collectCount }}
</span>
</div>
......@@ -82,23 +79,14 @@
</div>
<!-- 右侧:分页器 -->
<div class="right">
<div
class="pagination-wrapper bg-white rounded-lg shadow-sm border border-gray-100 p-3"
>
<el-pagination
v-model:current-page="searchParams.current"
v-model:page-size="searchParams.size"
:page-sizes="[15, 30, 45, 60]"
layout="prev, pager, next, jumper, total"
:total="total"
class="custom-pagination"
@current-change="
<div class="pagination-wrapper bg-white rounded-lg shadow-sm border border-gray-100 p-3">
<el-pagination v-model:current-page="searchParams.current" v-model:page-size="searchParams.size"
:page-sizes="[15, 30, 45, 60]" layout="prev, pager, next, jumper, total" :total="total"
class="custom-pagination" @current-change="
(e) => {
;(handleBackTop(), goToPage(e))
; (handleBackTop(), goToPage(e))
}
"
@size-change="changePageSize"
/>
" @size-change="changePageSize" />
</div>
</div>
</div>
......@@ -117,7 +105,7 @@
import { View, ChatDotRound, Star } from '@element-plus/icons-vue'
import { getColumnList } from '@/api'
import { usePageSearch, useScrollTop } from '@/hooks'
import { TABS_REF_KEY } from '@/constants'
import { ArticleTypeEnum, TABS_REF_KEY } from '@/constants'
import dayjs from 'dayjs'
import { useRouter } from 'vue-router'
const router = useRouter()
......
......@@ -2,44 +2,33 @@
<div>
<div v-loading="loading" v-if="list.length">
<div class="w-full max-w-6xl mx-auto">
<div
v-for="(item, index) in list"
:key="index"
class="bg-white rounded-lg shadow-sm mb-6 overflow-hidden"
:style="{ '--dynamic-color': item.color }"
>
<div
class="flex items-center justify-between pr-4 pl-4 pt-2 pb-2 bg-green-50 border-b border-green-100"
:style="{ backgroundColor: item.color, '--dynamic-color': item.color }"
>
<div v-for="(item, index) in list" :key="index" class="bg-white rounded-lg shadow-sm mb-6 overflow-hidden"
:style="{ '--dynamic-color': item.color }">
<div class="flex items-center justify-between pr-4 pl-4 pt-2 pb-2 bg-green-50 border-b border-green-100"
:style="{ backgroundColor: item.color, '--dynamic-color': item.color }">
<h3 class="text-lg font-medium text-gray-800 flex items-center">
<span class="w-1 h-5 mr-2 bg-#444"></span>
{{ item.title }}
</h3>
<div class="flex items-center cursor-pointer hover:text-[var(--dynamic-color)]">
<span class="mr-1 text-14px color-#606266 hover:text-[var(--dynamic-color)]"
>查看更多 >></span
>
<div class="flex items-center cursor-pointer hover:text-[var(--dynamic-color)]" @click="router.push({
path: '/searchPage',
query: {
type: ArticleTypeEnum.INTERVIEW
}
})">
<span class="mr-1 text-14px color-#606266 hover:text-[var(--dynamic-color)]">查看更多 >></span>
</div>
</div>
<div class="p-4">
<div v-if="item.yaColumnVoList.length" class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div
v-for="i in item.yaColumnVoList"
:key="i.articleId"
class="group cursor-pointer"
@click="router.push(`/articleDetail/${i.articleId}`)"
>
<div v-for="i in item.yaColumnVoList" :key="i.articleId" class="group cursor-pointer"
@click="router.push(`/articleDetail/${i.articleId}`)">
<div class="relative mb-3 overflow-hidden rounded-lg">
<img
:src="i.faceUrl"
class="w-full aspect-[5/3] object-cover group-hover:scale-105 transition-transform duration-300"
/>
<div
v-if="i.isRecommend"
class="absolute top-0 left-0 w-15 h-7 z-1000 bg-#FFF9B9 flex items-center justify-center border-2px border-solid border-#f4f0eb rounded-tl-lg rounded-br-lg"
>
<img :src="i.faceUrl"
class="w-full aspect-[5/3] object-cover group-hover:scale-105 transition-transform duration-300" />
<div v-if="i.isRecommend"
class="absolute top-0 left-0 w-15 h-7 z-1000 bg-#FFF9B9 flex items-center justify-center border-2px border-solid border-#f4f0eb rounded-tl-lg rounded-br-lg">
<img class="w-6" src="@/assets/img/culture/recommend.png" alt="" />
<div class="text-12px text-#000 line-height-12px">推荐</div>
</div>
......@@ -53,15 +42,21 @@
<div class="flex items-center justify-between text-xs text-gray-400">
<div class="flex items-center space-x-4">
<span class="flex items-center">
<el-icon class="mr-1"><View /></el-icon>
<el-icon class="mr-1">
<View />
</el-icon>
{{ i.viewCount }}
</span>
<span class="flex items-center">
<el-icon class="mr-1"><ChatDotRound /></el-icon>
<el-icon class="mr-1">
<ChatDotRound />
</el-icon>
{{ i.replyCount }}
</span>
<span class="flex items-center">
<el-icon class="mr-1"><Star /></el-icon>
<el-icon class="mr-1">
<Star />
</el-icon>
{{ i.collectCount }}
</span>
</div>
......@@ -84,23 +79,14 @@
</div>
<!-- 右侧:分页器 -->
<div class="right">
<div
class="pagination-wrapper bg-white rounded-lg shadow-sm border border-gray-100 p-3"
>
<el-pagination
v-model:current-page="searchParams.current"
v-model:page-size="searchParams.size"
:page-sizes="[15, 30, 45, 60]"
layout="prev, pager, next, jumper, total"
:total="total"
class="custom-pagination"
@current-change="
<div class="pagination-wrapper bg-white rounded-lg shadow-sm border border-gray-100 p-3">
<el-pagination v-model:current-page="searchParams.current" v-model:page-size="searchParams.size"
:page-sizes="[15, 30, 45, 60]" layout="prev, pager, next, jumper, total" :total="total"
class="custom-pagination" @current-change="
(e) => {
;(handleBackTop(), goToPage(e))
; (handleBackTop(), goToPage(e))
}
"
@size-change="changePageSize"
/>
" @size-change="changePageSize" />
</div>
</div>
</div>
......@@ -119,11 +105,12 @@
import { ArrowRight, View, ChatDotRound, Star } from '@element-plus/icons-vue'
import { getInterviewList } from '@/api'
import { usePageSearch, useScrollTop } from '@/hooks'
import { TABS_REF_KEY } from '@/constants'
import { TABS_REF_KEY, ArticleTypeEnum } from '@/constants'
import { useRouter } from 'vue-router'
import dayjs from 'dayjs'
const router = useRouter()
const tabsRef = inject(TABS_REF_KEY)
const { handleBackTop, ScrollTopComp } = useScrollTop(tabsRef!)
const { list, total, searchParams, goToPage, changePageSize, loading, refresh } = usePageSearch(
......
......@@ -6,26 +6,18 @@
<!-- 标签导航 -->
<div class="bg-white p-4 mb-6 rounded-lg shadow-sm">
<div class="flex flex-wrap gap-2 mb-2">
<el-tag
v-for="tag in filterOptions"
:key="tag.id"
<el-tag v-for="tag in filterOptions" :key="tag.id"
:type="tag.id === searchParams.sortLogic ? 'primary' : 'info'"
:effect="tag.id === searchParams.sortLogic ? 'dark' : 'plain'"
class="cursor-pointer"
@click="toggleFilter(tag.id)"
>
:effect="tag.id === searchParams.sortLogic ? 'dark' : 'plain'" class="cursor-pointer"
@click="toggleFilter(tag.id)">
{{ tag.title }}
</el-tag>
</div>
<div class="flex flex-wrap gap-2">
<el-tag
v-for="tag in tagList"
:key="tag.id"
<el-tag v-for="tag in tagList" :key="tag.id"
:type="searchParams.tagIdList?.includes(tag.id) ? 'primary' : 'info'"
:effect="searchParams.tagIdList?.includes(tag.id) ? 'dark' : 'plain'"
class="cursor-pointer"
@click="toggleTag(tag.id)"
>
:effect="searchParams.tagIdList?.includes(tag.id) ? 'dark' : 'plain'" class="cursor-pointer"
@click="toggleTag(tag.id)">
{{ tag.title }}
</el-tag>
</div>
......@@ -41,22 +33,20 @@
{{ filterText }}
</h2>
</div>
<div
class="text-#999 cursor-pointer text-sm"
@click="router.push(`/userPage?key=practice`)"
>
<div class="text-#999 cursor-pointer text-sm" @click="router.push({
path: '/searchPage',
query: {
type: ArticleTypeEnum.PRACTICE
}
})">
查看更多 >>
</div>
</div>
<el-divider class="my-1!" />
<div class="divide-y bg-#fff">
<div
@click="router.push(`/articleDetail/${item.id}`)"
v-for="item in list"
:key="item.id"
class="p-4 hover:bg-gray-50 transition-colors cursor-pointer"
>
<div @click="router.push(`/articleDetail/${item.id}`)" v-for="item in list" :key="item.id"
class="p-4 hover:bg-gray-50 transition-colors cursor-pointer">
<div class="flex gap-3 items-center">
<!-- 左侧内容 -->
<div class="flex-1">
......@@ -66,12 +56,8 @@
<!-- 带图片的内容 -->
<div class="flex gap-3 mb-3">
<img
v-if="item.faceUrl"
:src="item.faceUrl"
:alt="item.title"
class="w-20 h-20 object-cover rounded-lg flex-shrink-0"
/>
<img v-if="item.faceUrl" :src="item.faceUrl" :alt="item.title"
class="w-20 h-20 object-cover rounded-lg flex-shrink-0" />
<div class="flex-1">
<div class="text-gray-600 text-sm leading-relaxed line-clamp-3">
{{ item.content }}
......@@ -82,15 +68,21 @@
<!-- 互动数据 -->
<div class="flex items-center gap-4 text-gray-400 text-sm">
<div class="flex items-center gap-1">
<el-icon class="text-sm"><View /></el-icon>
<el-icon class="text-sm">
<View />
</el-icon>
<span>{{ item.viewCount }}</span>
</div>
<div class="flex items-center gap-1">
<el-icon class="text-sm"><ChatDotRound /></el-icon>
<el-icon class="text-sm">
<ChatDotRound />
</el-icon>
<span>{{ item.replyCount }}</span>
</div>
<div class="flex items-center gap-1">
<el-icon class="text-sm"><Star /></el-icon>
<el-icon class="text-sm">
<Star />
</el-icon>
<span>{{ item.praiseCount }}</span>
</div>
<div>{{ dayjs(item.createTime * 1000).format('YYYY-MM-DD HH:mm') }}</div>
......@@ -117,23 +109,14 @@
<!-- 右侧:分页器 -->
<div class="right">
<div
class="pagination-wrapper bg-white rounded-lg shadow-sm border border-gray-100 p-3"
>
<el-pagination
v-model:current-page="searchParams.current"
v-model:page-size="searchParams.size"
:page-sizes="[5, 20, 1]"
layout="prev, pager, next, jumper, total"
:total="total"
class="custom-pagination"
@current-change="
<div class="pagination-wrapper bg-white rounded-lg shadow-sm border border-gray-100 p-3">
<el-pagination v-model:current-page="searchParams.current" v-model:page-size="searchParams.size"
:page-sizes="[5, 20, 1]" layout="prev, pager, next, jumper, total" :total="total"
class="custom-pagination" @current-change="
(e) => {
;(handleBackTop(), goToPage(e))
; (handleBackTop(), goToPage(e))
}
"
@size-change="changePageSize"
/>
" @size-change="changePageSize" />
</div>
</div>
</div>
......
......@@ -2,42 +2,33 @@
<div>
<div v-loading="loading" v-if="list.length">
<div class="w-full max-w-6xl mx-auto">
<div
v-for="(item, index) in list"
:key="index"
class="bg-white rounded-lg shadow-sm mb-6 overflow-hidden"
:style="{ '--dynamic-color': item.color }"
>
<div
class="flex items-center justify-between pr-4 pl-4 pt-2 pb-2 bg-green-50 border-b border-green-100"
:style="{ backgroundColor: item.color, '--dynamic-color': item.color }"
>
<div v-for="(item, index) in list" :key="index" class="bg-white rounded-lg shadow-sm mb-6 overflow-hidden"
:style="{ '--dynamic-color': item.color }">
<div class="flex items-center justify-between pr-4 pl-4 pt-2 pb-2 bg-green-50 border-b border-green-100"
:style="{ backgroundColor: item.color, '--dynamic-color': item.color }">
<h3 class="text-lg font-medium text-gray-800 flex items-center">
<span class="w-1 h-5 mr-2 bg-#444"></span>
{{ item.title }}
</h3>
<div class="flex items-center cursor-pointer">
<div class="flex items-center cursor-pointer" @click="router.push({
path: '/searchPage',
query: {
type: ArticleTypeEnum.VIDEO
}
})">
<span class="mr-1 text-14px color-#606266">查看更多 >></span>
</div>
</div>
<div class="p-4">
<div v-if="item.yaColumnVoList.length" class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div
v-for="i in item.yaColumnVoList"
:key="i.articleId"
class="group cursor-pointer"
@click="router.push(`/articleDetail/${i.articleId}`)"
>
<div v-for="i in item.yaColumnVoList" :key="i.articleId" class="group cursor-pointer"
@click="router.push(`/articleDetail/${i.articleId}`)">
<div class="relative mb-3 overflow-hidden rounded-lg">
<img
:src="i.faceUrl"
class="w-full aspect-[5/3] object-cover group-hover:scale-105 transition-transform duration-300"
/>
<div
v-if="i.isRecommend"
class="absolute top--1 left--1 w-15 h-7 z-1000 bg-#FFF9B9 flex items-center justify-center border-2px border-solid border-#f4f0eb rounded-tl-lg rounded-br-lg"
>
<img :src="i.faceUrl"
class="w-full aspect-[5/3] object-cover group-hover:scale-105 transition-transform duration-300" />
<div v-if="i.isRecommend"
class="absolute top--1 left--1 w-15 h-7 z-1000 bg-#FFF9B9 flex items-center justify-center border-2px border-solid border-#f4f0eb rounded-tl-lg rounded-br-lg">
<img class="w-6" src="@/assets/img/culture/recommend.png" alt="" />
<div class="text-12px text-#000 line-height-12px">推荐</div>
</div>
......@@ -51,15 +42,21 @@
<div class="flex items-center justify-between text-xs text-gray-500">
<div class="flex items-center space-x-4">
<span class="flex items-center">
<el-icon class="mr-1"><View /></el-icon>
<el-icon class="mr-1">
<View />
</el-icon>
{{ i.viewCount }}
</span>
<span class="flex items-center">
<el-icon class="mr-1"><ChatDotRound /></el-icon>
<el-icon class="mr-1">
<ChatDotRound />
</el-icon>
{{ i.replyCount }}
</span>
<span class="flex items-center">
<el-icon class="mr-1"><Star /></el-icon>
<el-icon class="mr-1">
<Star />
</el-icon>
{{ i.collectCount }}
</span>
</div>
......@@ -82,23 +79,14 @@
</div>
<!-- 右侧:分页器 -->
<div class="right">
<div
class="pagination-wrapper bg-white rounded-lg shadow-sm border border-gray-100 p-3"
>
<el-pagination
v-model:current-page="searchParams.current"
v-model:page-size="searchParams.size"
:page-sizes="[15, 30, 45, 60]"
layout="prev, pager, next, jumper, total"
:total="total"
class="custom-pagination"
@current-change="
<div class="pagination-wrapper bg-white rounded-lg shadow-sm border border-gray-100 p-3">
<el-pagination v-model:current-page="searchParams.current" v-model:page-size="searchParams.size"
:page-sizes="[15, 30, 45, 60]" layout="prev, pager, next, jumper, total" :total="total"
class="custom-pagination" @current-change="
(e) => {
;(handleBackTop(), goToPage(e))
; (handleBackTop(), goToPage(e))
}
"
@size-change="changePageSize"
/>
" @size-change="changePageSize" />
</div>
</div>
</div>
......@@ -117,9 +105,10 @@
import { View, ChatDotRound, Star } from '@element-plus/icons-vue'
import { getVideoList } from '@/api'
import { usePageSearch, useScrollTop } from '@/hooks'
import { TABS_REF_KEY } from '@/constants'
import dayjs from 'dayjs'
import { TABS_REF_KEY, ArticleTypeEnum } from '@/constants'
import { useRouter } from 'vue-router'
import dayjs from 'dayjs'
const router = useRouter()
const tabsRef = inject(TABS_REF_KEY)
const { handleBackTop, ScrollTopComp } = useScrollTop(tabsRef!)
......
......@@ -4,13 +4,8 @@
<!-- 搜索栏 -->
<div class="mb-1 p-4">
<div class="relative flex items-center gap-3">
<el-input
v-model="searchParams.title"
placeholder="输入关键词搜索"
class="w-300px! flex-1"
@keyup.enter="handleSearch"
clearable
/>
<el-input v-model="searchParams.title" placeholder="输入关键词搜索" class="w-300px! flex-1"
@keyup.enter="handleSearch" clearable />
<el-button type="primary" @click="handleSearch"> 搜索 </el-button>
</div>
</div>
......@@ -20,33 +15,18 @@
<div class="flex items-center gap-2">
<span class="text-gray-600 text-14px">分类:</span>
<div class="flex gap-2">
<button
v-for="sort in articleTypeListOptions"
:key="sort.value"
class="px-4 py-1.5 rounded-lg text-14px transition-colors cursor-pointer"
:class="{
<button v-for="sort in [{ label: '全部', value: '' }, ...articleTypeListOptions]" :key="sort.value"
class="px-4 py-1.5 rounded-lg text-14px transition-colors cursor-pointer" :class="{
'text-blue-600 bg-blue-50': searchParams.type === sort.value,
'text-gray-600 hover:text-blue-600': searchParams.type !== sort.value,
}"
@click="changeType(sort.value)"
>
}" @click="changeType(sort.value)">
{{ sort.label }}
</button>
</div>
</div>
<div class="text-gray-500 text-14px">
<el-select
v-model="searchParams.sortLogic"
placeholder="请选择排序方式"
class="w-100px!"
@change="changeSort"
>
<el-option
v-for="sort in sortOptions"
:key="sort.value"
:label="sort.label"
:value="sort.value"
/>
<el-select v-model="searchParams.sortLogic" placeholder="请选择排序方式" class="w-100px!" @change="changeSort">
<el-option v-for="sort in sortOptions" :key="sort.value" :label="sort.label" :value="sort.value" />
</el-select>
</div>
</div>
......@@ -77,22 +57,15 @@
<div v-show="list.length">
<div class="space-y-4">
<div
v-for="item in list"
:key="item.id"
<div v-for="item in list" :key="item.id"
class="flex gap-4 p-4 rounded-lg hover:bg-gray-50 transition-colors cursor-pointer"
@click="handleClick(item)"
>
@click="handleClick(item)">
<!-- 封面图 -->
<div
v-if="item.faceUrl"
class="flex-shrink-0 w-240px h-135px rounded-lg overflow-hidden bg-gray-100 relative"
>
<div v-if="item.faceUrl"
class="flex-shrink-0 w-240px h-135px rounded-lg overflow-hidden bg-gray-100 relative">
<img :src="item.faceUrl" class="w-full h-full object-cover" />
<div
v-if="item.type === ArticleTypeEnum.VIDEO"
class="absolute bottom-2 right-2 bg-black/70 text-white text-12px px-2 py-0.5 rounded"
>
<div v-if="item.type === ArticleTypeEnum.VIDEO"
class="absolute bottom-2 right-2 bg-black/70 text-white text-12px px-2 py-0.5 rounded">
{{ item.videoDuration }}
</div>
</div>
......@@ -116,15 +89,21 @@
<span>{{ item.showName }}</span>
<span>{{ dayjs(item.createTime * 1000).format('YYYY-MM-DD HH:mm:ss') }}</span>
<div class="flex items-center gap-1">
<el-icon class="text-sm"><View /></el-icon>
<el-icon class="text-sm">
<View />
</el-icon>
<span class="font-medium text-gray-500">{{ item.viewCount }}</span>
</div>
<div class="flex items-center gap-1">
<el-icon class="text-sm"><ChatDotRound /></el-icon>
<el-icon class="text-sm">
<ChatDotRound />
</el-icon>
<span class="font-medium">{{ item.replyCount }}</span>
</div>
<div class="flex items-center gap-1">
<el-icon class="text-sm"><Star /></el-icon>
<el-icon class="text-sm">
<Star />
</el-icon>
<span class="font-medium">{{ item.praiseCount }}</span>
</div>
</div>
......@@ -148,23 +127,14 @@
<!-- 右侧:分页器 -->
<div class="right">
<div
class="pagination-wrapper bg-white rounded-lg shadow-sm border border-gray-100 p-3"
>
<el-pagination
v-model:current-page="searchParams.current"
v-model:page-size="searchParams.size"
:page-sizes="[5, 20, 1]"
layout="prev, pager, next, jumper, total"
:total="total"
class="custom-pagination"
@current-change="
<div class="pagination-wrapper bg-white rounded-lg shadow-sm border border-gray-100 p-3">
<el-pagination v-model:current-page="searchParams.current" v-model:page-size="searchParams.size"
:page-sizes="[5, 20, 1]" layout="prev, pager, next, jumper, total" :total="total"
class="custom-pagination" @current-change="
(e) => {
;(handleBackTop(), goToPage(e))
; (handleBackTop(), goToPage(e))
}
"
@size-change="changePageSize"
/>
" @size-change="changePageSize" />
</div>
</div>
</div>
......@@ -193,6 +163,10 @@ const route = useRoute()
const searchPageRef = ref<HTMLElement | null>(null)
const { ScrollTopComp, handleBackTop } = useScrollTop(searchPageRef)
const queryType = route.query.type || '' as ArticleTypeEnum | undefined
const querySearchTitle = route.query.title
const sortOptions = [
{ label: '最热', value: 0 },
{ label: '最新', value: 1 },
......@@ -202,8 +176,9 @@ const { total, goToPage, changePageSize, refresh, searchParams, list } = usePage
getArticleList,
{
defaultParams: {
type: articleTypeListOptions[0]?.value,
type: queryType || '',
sortLogic: sortOptions[0]?.value,
title: querySearchTitle || '',
},
immediate: false,
},
......@@ -231,12 +206,8 @@ const handleClick = (item: ArticleListItemDto) => {
}
onActivated(() => {
if (route.query.title) {
searchParams.value.title = route.query.title as string
}
if (route.query.type) {
searchParams.value.type = route.query.type as ArticleTypeEnum
}
searchParams.value.title = route.query.title || ''
searchParams.value.type = route.query.type || ''
refresh()
})
</script>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment