Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
corporateCulture-qd
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
王立鹏
corporateCulture-qd
Commits
76422e6d
Commit
76422e6d
authored
Mar 04, 2026
by
lijiabin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
【需求 20331】 styles: 基本上是一些样式优化
parent
e5a127c9
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
527 additions
and
525 deletions
+527
-525
index.ts
src/api/index.ts
+0
-3
options.ts
src/constants/options.ts
+4
-5
onlineTime.vue
src/layoutCulture/components/onlineTime.vue
+32
-67
index.ts
src/stores/index.ts
+1
-0
onlineTime.ts
src/stores/onlineTime.ts
+8
-0
user.ts
src/stores/user.ts
+1
-1
index.ts
src/utils/request/index.ts
+2
-2
index.vue
src/views/auction/index.vue
+130
-110
lotteryConfigDialog.vue
...enu/dailyLotteryManage/components/lotteryConfigDialog.vue
+9
-0
index.vue
src/views/homePage/askTab/index.vue
+65
-108
recommendList.vue
src/views/homePage/homeTab/components/recommendList.vue
+12
-17
columnList.vue
src/views/homePage/yaTab/components/columnList.vue
+46
-50
interviewList.vue
src/views/homePage/yaTab/components/interviewList.vue
+46
-57
practiceList.vue
src/views/homePage/yaTab/components/practiceList.vue
+40
-45
exchangeContent.tsx
src/views/pointsStore/components/exchangeContent.tsx
+40
-32
index.vue
src/views/pointsStore/index.vue
+85
-27
index.vue
src/views/userPage/index.vue
+6
-1
No files found.
src/api/index.ts
View file @
76422e6d
// 企业文化接口
// 企业文化接口
export
*
from
'./task'
export
*
from
'./task'
export
*
from
'./sign'
export
*
from
'./sign'
export
*
from
'./article'
export
*
from
'./shop'
export
*
from
'./shop'
export
*
from
'./tag'
export
*
from
'./tag'
export
*
from
'./article'
export
*
from
'./user'
export
*
from
'./user'
export
*
from
'./case'
export
*
from
'./case'
export
*
from
'./home'
export
*
from
'./home'
...
@@ -19,7 +17,6 @@ export * from './dailyLottery'
...
@@ -19,7 +17,6 @@ export * from './dailyLottery'
// 导出类型
// 导出类型
export
*
from
'./task/types'
export
*
from
'./task/types'
export
*
from
'./shop/types'
export
*
from
'./shop/types'
export
*
from
'./article/types'
export
*
from
'./tag/types'
export
*
from
'./tag/types'
export
*
from
'./article/types'
export
*
from
'./article/types'
export
*
from
'./user/types'
export
*
from
'./user/types'
...
...
src/constants/options.ts
View file @
76422e6d
...
@@ -76,6 +76,10 @@ export const articleTypeListOptionsForReal: { label: string; value: ArticleTypeE
...
@@ -76,6 +76,10 @@ export const articleTypeListOptionsForReal: { label: string; value: ArticleTypeE
label
:
'专访'
,
label
:
'专访'
,
value
:
ArticleTypeEnum
.
INTERVIEW
,
value
:
ArticleTypeEnum
.
INTERVIEW
,
},
},
{
label
:
'问吧'
,
value
:
ArticleTypeEnum
.
QUESTION
,
},
]
]
export
const
articleTypeListOptionsForNotReal
:
{
label
:
string
;
value
:
ArticleTypeEnum
}[]
=
[
export
const
articleTypeListOptionsForNotReal
:
{
label
:
string
;
value
:
ArticleTypeEnum
}[]
=
[
...
@@ -88,11 +92,6 @@ export const articleTypeListOptionsForNotReal: { label: string; value: ArticleTy
...
@@ -88,11 +92,6 @@ export const articleTypeListOptionsForNotReal: { label: string; value: ArticleTy
value
:
ArticleTypeEnum
.
VIDEO
,
value
:
ArticleTypeEnum
.
VIDEO
,
},
},
{
{
label
:
'问吧'
,
value
:
ArticleTypeEnum
.
QUESTION
,
},
{
label
:
'专栏'
,
label
:
'专栏'
,
value
:
ArticleTypeEnum
.
COLUMN
,
value
:
ArticleTypeEnum
.
COLUMN
,
},
},
...
...
src/layoutCulture/components/onlineTime.vue
View file @
76422e6d
<
template
>
<
template
>
<Draggable
<Draggable
v-show=
"showOnlineTime"
:initial-value=
"
{ x: x, y: y }"
:initial-value=
"
{ x: x, y: y }"
storage-key="vueuse-draggable"
storage-key="vueuse-draggable"
storage-type="session"
storage-type="session"
class="fixed"
class="fixed
z-2
"
>
>
<div
class=
"cursor-pointer online-time flex flex-col items-center z-10050"
>
<div
<!-- 图片容器 -->
class=
"group flex items-center gap-2.5 py-2.5 pr-4 pl-3 bg-#fff rounded-xl shadow-[inset_0_2px_6px_rgba(0,0,0,0.08)] cursor-pointer transition-all duration-250 relative shadow-[inset_0_2px_8px_rgba(0,0,0,0.12)]"
>
<!-- 在线指示灯 -->
<div
<div
class=
"mb-4 w-24 h-24 bg-white rounded-full shadow-xl flex items-center justify-center hover:scale-110 transition-transform cursor-pointer"
class=
"w-1.5 h-1.5 rounded-full bg-green-500 shrink-0 animate-pulse shadow-[0_0_6px_rgba(34,197,94,0.4)]"
>
></div>
<img
src=
"@/assets/img/culture/ask.png"
draggable=
"false"
alt=
"吉祥物"
class=
"w-20 h-20"
/>
<!-- 如果没有图片,用emoji代替 -->
<!-- 时长内容 -->
<!--
<span
class=
"text-6xl"
>
🎯
</span>
-->
<div
class=
"flex flex-col leading-tight"
>
<span
class=
"text-base text-gray-400 tracking-wider font-medium"
>
今日在线时长
</span>
<span
class=
"text-base font-bold text-blue-600 tabular-nums tracking-wider"
>
{{
formatSeconds
}}
</span>
</div>
</div>
<!--
时长显示卡片
-->
<!--
关闭按钮
-->
<div
<div
class=
"w-24 md:w-28 lg:w-32 h-16 md:h-18 lg:h-20 rounded-lg bg-gradient-to-br from-white via-blue-50 to-purple-50 shadow-lg hover:shadow-xl border border-white/50 flex flex-col justify-center items-center transition-all duration-300 ease-out hover:scale-105 hover:-translate-y-1 backdrop-blur-sm relative overflow-hidden group transform-gpu backface-hidden will-change-transform"
class=
"absolute -top-1.5 -right-1.5 w-4 h-4 rounded-full bg-white text-gray-400 shadow-sm flex items-center justify-center opacity-0 scale-60 transition-all duration-200 cursor-pointer group-hover:opacity-100 group-hover:scale-100 hover:!bg-red-500 hover:!text-white"
title=
"关闭"
@
click
.
stop=
"showOnlineTime = false"
>
>
<!-- 其他内容保持不变 -->
<svg
viewBox=
"0 0 12 12"
class=
"w-2.5 h-2.5"
>
<div
<path
class=
"absolute inset-0 bg-gradient-to-r from-blue-400/5 via-purple-400/5 to-pink-400/5 opacity-0 group-hover:opacity-100 transition-opacity duration-500"
d=
"M1.5.4L6 4.9 10.5.4l1.1 1.1L7.1 6l4.5 4.5-1.1 1.1L6 7.1 1.5 11.6.4 10.5 4.9 6 .4 1.5z"
></div>
fill=
"currentColor"
/>
<div
</svg>
class=
"absolute top-0 left-0 right-0 h-2 bg-gradient-to-r from-blue-400 via-purple-400 to-pink-400 opacity-80"
></div>
<div
class=
"absolute top-1 left-0 right-0 h-1 bg-gradient-to-r from-blue-300 via-purple-300 to-pink-300 opacity-60"
></div>
<div
class=
"text-center px-3 relative"
>
<div
class=
"text-xs md:text-sm text-gray-700 font-medium mb-1 tracking-wide"
>
今日在线时长
</div>
<div
class=
"text-center text-2xl font-bold bg-gradient-to-r from-blue-500 to-purple-500 bg-clip-text text-transparent"
>
{{
formatSeconds
}}
</div>
</div>
<div
class=
"absolute bottom-2 left-3 right-3 h-1 bg-gray-200 rounded-full overflow-hidden"
>
<div
class=
"h-full bg-gradient-to-r from-blue-400 to-purple-400 rounded-full animate-pulse"
:style=
"
{
width: widthRate + '%',
}"
>
</div>
</div>
<div
class=
"absolute top-3 right-3 w-2 h-2 bg-green-400 rounded-full animate-pulse"
></div>
<div
class=
"absolute bottom-3 left-3 w-1.5 h-1.5 bg-blue-400 rounded-full animate-pulse"
style=
"animation-delay: 0.8s"
></div>
<div
class=
"absolute left-0 top-4 bottom-4 w-0.5 bg-gradient-to-b from-transparent via-purple-300 to-transparent opacity-50"
></div>
<div
class=
"absolute right-0 top-4 bottom-4 w-0.5 bg-gradient-to-b from-transparent via-blue-300 to-transparent opacity-50"
></div>
</div>
</div>
</div>
</div>
</Draggable>
</Draggable>
</
template
>
</
template
>
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
{
UseDraggable
as
Draggable
}
from
'@vueuse/components'
import
{
UseDraggable
as
Draggable
}
from
'@vueuse/components'
import
{
useWindowSize
}
from
'@vueuse/core'
import
{
useWindowSize
}
from
'@vueuse/core'
import
{
getTodayOnlineSeconds
,
heartbeat
}
from
'@/api'
import
{
getTodayOnlineSeconds
,
heartbeat
}
from
'@/api'
import
dayjs
from
'dayjs'
import
dayjs
from
'dayjs'
import
utc
from
'dayjs/plugin/utc'
import
utc
from
'dayjs/plugin/utc'
import
{
useOnlineTimeStore
}
from
'@/stores'
import
{
storeToRefs
}
from
'pinia'
dayjs
.
extend
(
utc
)
dayjs
.
extend
(
utc
)
const
onlineTimeStore
=
useOnlineTimeStore
()
const
{
showOnlineTime
}
=
storeToRefs
(
onlineTimeStore
)
const
{
height
}
=
useWindowSize
()
const
{
height
}
=
useWindowSize
()
const
CONTAINER_HEIGHT
=
170
,
const
CONTAINER_HEIGHT
=
170
,
GAP
=
30
GAP
=
30
// CONTAINER_WIDTH = 130
const
maxSeconds
=
60
*
30
// 半小时
const
x
=
GAP
const
x
=
GAP
const
y
=
height
.
value
-
CONTAINER_HEIGHT
-
GAP
const
y
=
height
.
value
-
CONTAINER_HEIGHT
-
GAP
const
currentSeconds
=
ref
(
0
)
const
currentSeconds
=
ref
(
0
)
// 进度条的比例
const
widthRate
=
computed
(()
=>
{
if
(
currentSeconds
.
value
>=
maxSeconds
)
{
return
100
}
else
{
return
(
currentSeconds
.
value
/
maxSeconds
)
*
100
}
})
// 在线时长格式化 将秒级 格式化为 00:00
// 如果大于一个小时的话,则显示小时:分钟:秒
const
formatSeconds
=
computed
(()
=>
{
const
formatSeconds
=
computed
(()
=>
{
if
(
currentSeconds
.
value
>=
60
*
60
)
{
if
(
currentSeconds
.
value
>=
60
*
60
)
{
return
dayjs
.
utc
(
currentSeconds
.
value
*
1000
).
format
(
'hh:mm:ss'
)
return
dayjs
.
utc
(
currentSeconds
.
value
*
1000
).
format
(
'hh:mm:ss'
)
...
...
src/stores/index.ts
View file @
76422e6d
...
@@ -5,3 +5,4 @@ export * from './interview'
...
@@ -5,3 +5,4 @@ export * from './interview'
export
*
from
'./video'
export
*
from
'./video'
export
*
from
'./question'
export
*
from
'./question'
export
*
from
'./yabi'
export
*
from
'./yabi'
export
*
from
'./onlineTime'
src/stores/onlineTime.ts
0 → 100644
View file @
76422e6d
import
{
defineStore
}
from
'pinia'
export
const
useOnlineTimeStore
=
defineStore
(
'onlineTime'
,
()
=>
{
const
showOnlineTime
=
ref
(
true
)
return
{
showOnlineTime
,
}
})
src/stores/user.ts
View file @
76422e6d
...
@@ -47,7 +47,7 @@ export const useUserStore = defineStore('user', () => {
...
@@ -47,7 +47,7 @@ export const useUserStore = defineStore('user', () => {
const
{
data
}
=
await
refreshTokenApi
(
refreshToken
.
value
)
const
{
data
}
=
await
refreshTokenApi
(
refreshToken
.
value
)
setUserInfoAndToken
(
data
)
setUserInfoAndToken
(
data
)
}
}
const
setUserInfoAndToken
=
async
(
data
:
LoginResponseDto
)
=>
{
const
setUserInfoAndToken
=
(
data
:
LoginResponseDto
)
=>
{
setUserInfo
(
data
)
setUserInfo
(
data
)
setToken
(
data
.
token
)
setToken
(
data
.
token
)
setRefreshToken
(
data
.
refreshToken
)
setRefreshToken
(
data
.
refreshToken
)
...
...
src/utils/request/index.ts
View file @
76422e6d
import
{
app_config
}
from
'@/config'
import
{
app_config
}
from
'@/config'
import
Ax
oi
s
from
'./axios'
import
Ax
io
s
from
'./axios'
// 'http://192.168.2.168:8089'
// 'http://192.168.2.168:8089'
const
baseUrl
=
app_config
[
import
.
meta
.
env
.
MODE
]?.
baseUrl
const
baseUrl
=
app_config
[
import
.
meta
.
env
.
MODE
]?.
baseUrl
console
.
log
(
'baseUrl'
,
baseUrl
)
console
.
log
(
'baseUrl'
,
baseUrl
)
export
default
new
Ax
oi
s
({
export
default
new
Ax
io
s
({
baseURL
:
baseUrl
,
baseURL
:
baseUrl
,
timeout
:
1000
*
60
,
timeout
:
1000
*
60
,
})
})
src/views/auction/index.vue
View file @
76422e6d
...
@@ -100,49 +100,69 @@ const onBid = async (item: AuctionItemDto) => {
...
@@ -100,49 +100,69 @@ const onBid = async (item: AuctionItemDto) => {
console
.
log
(
data
,
'data'
)
console
.
log
(
data
,
'data'
)
const
val
=
ref
(
0
)
const
val
=
ref
(
0
)
ElMessageBox
.
confirm
(
'确定参与竞拍吗?'
,
{
ElMessageBox
.
confirm
(
'确定参与竞拍吗?'
,
{
confirmButtonText
:
'确
定
'
,
confirmButtonText
:
'确
认出价
'
,
cancelButtonText
:
'取消'
,
cancelButtonText
:
'取消'
,
customClass
:
'auction-bid-dialog'
,
message
:
()
=>
(
message
:
()
=>
(
<
div
class
=
"space-y-12px text-gray-700"
>
<
div
class
=
"space-y-16px"
>
{
/* 作品名称 */
}
{
/* 商品名称 */
}
<
div
class
=
"text-16px font-600 text-gray-900"
>
{
item
.
name
}
<
/div
>
<
div
class
=
"flex items-center gap-3"
>
<
img
src
=
{
item
.
imageUrl
}
class
=
"w-12 h-12 rounded-lg object-cover shadow-sm"
/>
<
div
>
<
div
class
=
"text-15px font-600 text-gray-800 line-clamp-1"
>
{
item
.
name
}
<
/div
>
<
div
class
=
"text-12px text-gray-400 mt-1"
>
{
item
.
specification
}
<
/div
>
<
/div
>
<
/div
>
{
/* 规则说明 */
}
{
/* 规则说明 */
}
<
div
class
=
"text-12px leading-18px text-gray-500 bg-gray-50 rounded-6px p-10px"
>
<
div
class
=
"text-12px leading-18px text-indigo-500 bg-indigo-50 rounded-8px px-12px py-8px flex items-start gap-6px"
>
竞拍后将暂时扣除您出价的
YA
币,若您的出价被超越,
YA
币将自动退回
<
span
class
=
"mt-2px shrink-0"
>
💡
<
/span
>
<
span
>
竞拍后将暂时扣除您出价的
YA
币,若您的出价被超越,
YA
币将自动退回
<
/span
>
<
/div
>
<
/div
>
{
/* 当前竞拍信息 */
}
{
/* 当前竞拍信息 */
}
<
div
class
=
"
space-y-6
px"
>
<
div
class
=
"
bg-gray-50 rounded-10px p-12px space-y-8
px"
>
{
data
.
currentPrice
?
(
{
data
.
currentPrice
?
(
<
div
class
=
"flex items-center justify-between"
>
<
div
class
=
"flex items-center justify-between"
>
<
span
class
=
"text-gray-500"
>
当前最高出价
<
/span
>
<
span
class
=
"text-13px text-gray-500"
>
当前最高出价
<
/span
>
<
span
class
=
"text-orange-500 font-600"
>
{
data
.
currentPrice
}
YA
币
<
/span
>
<
span
class
=
"text-16px text-orange-500 font-700"
>
{
data
.
currentPrice
}
<
span
class
=
"text-12px font-400"
>
YA
币
<
/span
>
<
/span
>
<
/div
>
<
/div
>
)
:
(
)
:
(
<
div
class
=
"text-gray-500"
>
当前暂未有人出价
<
/div
>
<
div
class
=
"flex items-center justify-between"
>
<
span
class
=
"text-13px text-gray-500"
>
当前最高出价
<
/span
>
<
span
class
=
"text-13px text-gray-400"
>
暂无人出价
<
/span
>
<
/div
>
)}
)}
<
div
class
=
"flex items-center justify-between"
>
<
div
class
=
"flex items-center justify-between"
>
<
span
class
=
"text-gray-500"
>
单人出价上限
<
/span
>
<
span
class
=
"text-13px text-gray-500"
>
起拍价
<
/span
>
<
span
class
=
"text-gray-700"
>
{
item
.
bidLimit
}
次
<
/span
>
<
span
class
=
"text-13px text-gray-700 font-500"
>
{
data
.
startingPrice
}
YA
币
<
/span
>
<
/div
>
<
div
class
=
"flex items-center justify-between"
>
<
span
class
=
"text-13px text-gray-500"
>
最低加价
<
/span
>
<
span
class
=
"text-13px text-gray-700 font-500"
>
{
data
.
minIncrement
}
YA
币
<
/span
>
<
/div
>
<
div
class
=
"flex items-center justify-between"
>
<
span
class
=
"text-13px text-gray-500"
>
出价次数上限
<
/span
>
<
span
class
=
"text-13px text-gray-700 font-500"
>
{
item
.
bidLimit
}
次
<
/span
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
{
/* 出价输入 */
}
{
/* 出价输入 */
}
<
div
class
=
"space-y-
6px flex items-center justify-between
"
>
<
div
class
=
"space-y-
8px
"
>
<
div
class
=
"text-
gray-500"
>
您的出价
<
/div
>
<
div
class
=
"text-
13px text-gray-700 font-500"
>
您的出价
(
YA
币
)
<
/div
>
<
el
-
input
-
number
<
el
-
input
-
number
v
-
model
=
{
val
.
value
}
v
-
model
=
{
val
.
value
}
controls
-
position
=
"right"
controls
-
position
=
"right"
class
=
"w-50%!"
class
=
"w-full!"
placeholder
=
"请输入 YA 币数量"
min
=
{
0
}
placeholder
=
"请输入出价金额"
/>
/>
<
/div
>
<
div
class
=
"flex items-center justify-end text-12px text-gray-400"
>
可用余额:
<
span
class
=
"text-indigo-500 font-500"
>
{
yabiData
.
value
.
currentValue
}
<
/span>{' '
}
{
/* 余额提示 */
}
YA
币
<
div
class
=
"flex items-center justify-end text-12px text-gray-500 rounded-6px p-8px"
>
<
/div
>
<
span
>
当前可用
{
yabiData
.
value
.
currentValue
}
YA
币
<
/span
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
),
),
...
@@ -221,52 +241,52 @@ const onBid = async (item: AuctionItemDto) => {
...
@@ -221,52 +241,52 @@ const onBid = async (item: AuctionItemDto) => {
</button>
</button>
</div>
</div>
<template
v-if=
"list.length"
>
<template
v-if=
"list.length"
>
<!-- 卡片网格 -->
<div
class=
"grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-5"
>
<div
class=
"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3 gap-6"
>
<div
<div
v-for=
"item in list"
v-for=
"item in list"
:key=
"item.id"
:key=
"item.id"
class=
"card group relative bg-white rounded-xl overflow-hidden border
-2 border-solid border-transparent shadow-lg hover:border-blue-500 hover:shadow-xl transition-all duration-300 cursor-pointer transform hover:-translate-y-1
"
class=
"card group relative bg-white rounded-xl overflow-hidden border
border-gray-100 shadow-sm hover:shadow-lg transition-all duration-300 cursor-pointer hover:-translate-y-0.5
"
:class=
"
{ 'filter-grayscale-30': item.status === AuctionStatusEnum.AUCTION_FAILED }"
:class=
"
{ 'filter-grayscale-30': item.status === AuctionStatusEnum.AUCTION_FAILED }"
>
>
<!-- 状态角标 -->
<!-- 图片区 -->
<div
<div
class=
"card-img-wrap relative aspect-4/3 overflow-hidden bg-gray-100"
>
class=
"absolute top-2 left-2 z-2 text-xs font-semibold px-2.5 py-1 rounded-full tracking-wide"
:class=
"getBadgeClass(item.status)"
>
{{
tabs
.
find
((
option
)
=>
option
.
value
===
item
.
status
)?.
label
}}
</div>
<!-- 图片容器 -->
<div
class=
"card-img-wrap w-full aspect-6/5 bg-gradient-to-br from-blue-50 to-purple-50 flex items-center justify-center relative overflow-hidden"
>
<img
<img
:src=
"item.imageUrl"
:src=
"item.imageUrl"
class=
"w-full h-full object-cover transition-transform duration-300 group-hover:scale-105"
class=
"w-full h-full object-cover transition-transform duration-300 group-hover:scale-105"
/>
/>
<!-- 悬浮层 -->
<!-- 状态角标 -->
<!--
<div
<div
class=
"absolute inset-0 bg-black/0 group-hover:bg-black/15 transition-all duration-300 flex items-center justify-center opacity-0 group-hover:opacity-100"
class=
"absolute top-2.5 left-2.5 text-11px font-semibold px-2.5 py-1 rounded-md tracking-wide shadow-sm"
:class=
"getBadgeClass(item.status)"
>
{{
tabs
.
find
((
option
)
=>
option
.
value
===
item
.
status
)?.
label
}}
</div>
<!-- 倒计时条 -->
<div
v-if=
"item.status === AuctionStatusEnum.AUCTIONING"
class=
"absolute bottom-0 inset-x-0 bg-black/60 backdrop-blur-sm text-white text-11px py-1.5 px-3 flex items-center gap-1.5"
>
>
<span
<span
class=
"bg-white px-4 py-2 rounded-full text-sm font-medium text-blue-600 shadow-md transition-all duration-300"
class=
"inline-block w-1.5 h-1.5 rounded-full bg-red-400 animate-pulse"
>
></span>
查看详情
{{
item
.
remainingTime
}}
</span>
</div>
</div>
-->
</div>
</div>
<!-- 内容区 -->
<!-- 内容区 -->
<div
class=
"card-body p-5 flex flex-col gap-2"
>
<div
class=
"p-4 flex flex-col gap-2"
>
<!-- 标题 -->
<!-- 标题 + 规格 -->
<h3
class=
"text-[15px] font-semibold text-gray-900 leading-snug line-clamp-1"
>
<div
class=
"flex items-center justify-between gap-2"
>
{{
item
.
name
}}
<h3
class=
"text-sm font-semibold text-gray-800 line-clamp-1"
>
</h3>
{{
item
.
name
}}
</h3>
<span
class=
"text-11px text-gray-400 shrink-0"
>
{{
item
.
specification
}}
</span>
</div>
<!-- 描述 -->
<!-- 描述 -->
<p
class=
"text-xs text-gray-
500 leading-relaxed
line-clamp-1"
>
<p
class=
"text-xs text-gray-
400
line-clamp-1"
>
<el-popover
:content=
"item.description"
placement=
"top-start"
width=
"300"
>
<el-popover
:content=
"item.description"
placement=
"top-start"
width=
"300"
>
<template
#
reference
>
<template
#
reference
>
{{
item
.
description
}}
{{
item
.
description
}}
...
@@ -274,47 +294,45 @@ const onBid = async (item: AuctionItemDto) => {
...
@@ -274,47 +294,45 @@ const onBid = async (item: AuctionItemDto) => {
</el-popover>
</el-popover>
</p>
</p>
<!-- 规格 -->
<!-- 分隔线 -->
<div
class=
"flex items-center gap-1 text-xs text-gray-600"
>
<div
class=
"border-t border-dashed border-gray-100 my-1"
></div>
<span
class=
"text-gray-400"
>
规格
</span>
<span
class=
"text-gray-700 font-medium"
>
{{ item.specification }}
</span>
</div>
<!-- 剩余时间(单独一行,重要) -->
<div
class=
"text-xs text-gray-500 mt-1"
:style=
"{
opacity: item.status === AuctionStatusEnum.AUCTIONING ? 1 : 0,
}"
>
⏱ 拍卖剩余:{{ item.remainingTime }}
</div>
<!--
底部价格 + 按钮
-->
<!--
价格区
-->
<div
class=
"flex items-end justify-between gap-2"
>
<div
class=
"flex items-end justify-between gap-2"
>
<div
class=
"flex flex-col"
>
<div
class=
"flex flex-col gap-0.5"
>
<div
v-if=
"item.currentPrice"
class=
"flex items-baseline gap-1"
>
<span
class=
"text-11px text-gray-400"
>
当前出价
</span>
<span
class=
"text-lg font-bold text-orange-500"
>
{{
item.currentPrice
}}
</span>
<span
class=
"text-11px text-gray-400"
>
YA币
</span>
</div>
<div
class=
"flex items-baseline gap-1"
>
<div
class=
"flex items-baseline gap-1"
>
<span
class=
"text-xs text-gray-400"
>
起拍
</span>
<span
class=
"text-11px text-gray-400"
>
起拍价
</span>
<span
class=
"text-lg font-bold text-red-500"
>
<span
class=
"font-semibold"
:class=
"
item.currentPrice
? 'text-xs text-gray-400 line-through'
: 'text-lg text-orange-500'
"
>
{{ item.startingPrice }}
{{ item.startingPrice }}
</span>
</span>
<span
class=
"text-xs text-gray-5
00"
>
YA币
</span>
<span
v-if=
"!item.currentPrice"
class=
"text-11px text-gray-4
00"
>
YA币
</span>
</div>
</div>
<div
class=
"text-xs text-gray-400"
>
<div
class=
"text-11px text-gray-400"
>
最低加价
加价幅度 ≥ {{ item.minIncrement }} YA币
<span
class=
"text-gray-600 font-medium"
>
{{ item.minIncrement }}
</span>
YA币
</div>
</div>
</div>
</div>
<
el-
button
<button
v-if=
"item.status === AuctionStatusEnum.AUCTIONING"
v-if=
"item.status === AuctionStatusEnum.AUCTIONING"
type=
"primary"
class=
"shrink-0 px-4 py-1.5 rounded-lg text-xs font-medium bg-gradient-to-r from-indigo-500 to-purple-500 text-white shadow-sm shadow-indigo-500/20 hover:shadow-md hover:shadow-indigo-500/30 active:scale-95 transition-all duration-200 cursor-pointer"
size=
"small"
class=
"bg-gradient-to-r from-indigo-500 to-purple-600 text-white border-none px-4 py-2 rounded-lg shadow-md hover:shadow-lg transition-all"
@
click
.
stop=
"onBid(item)"
@
click
.
stop=
"onBid(item)"
>
>
参与竞拍
🔨 出价
</
el-
button>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
...
@@ -402,44 +420,46 @@ const onBid = async (item: AuctionItemDto) => {
...
@@ -402,44 +420,46 @@ const onBid = async (item: AuctionItemDto) => {
</template>
</template>
<
style
scoped
>
<
style
scoped
>
/* 已结束卡片置灰 */
.card.filter-grayscale-30
{
.card.filter-grayscale-30
{
filter
:
grayscale
(
30%
);
filter
:
grayscale
(
30%
);
}
}
</
style
>
/* 图片光圈装饰 (UnoCSS 复杂渐变伪元素不易直接实现,保留为 scoped CSS) */
<
style
>
.card-img-wrap
::before
{
.auction-bid-dialog
.el-message-box__header
{
content
:
''
;
display
:
none
;
position
:
absolute
;
width
:
120px
;
height
:
120px
;
border-radius
:
50%
;
background
:
radial-gradient
(
circle
,
rgba
(
139
,
92
,
246
,
0.12
)
0%
,
transparent
70%
);
top
:
50%
;
left
:
50%
;
transform
:
translate
(
-50%
,
-50%
);
transition
:
transform
0.3s
ease
;
z-index
:
0
;
/* 确保在图片下方 */
}
}
/* 悬浮时光圈放大效果 */
.auction-bid-dialog
.el-message-box__content
{
.card
:hover
.card-img-wrap
::before
{
padding
:
24px
24px
8px
;
transform
:
translate
(
-50%
,
-50%
)
scale
(
1.1
);
}
}
.bid-btn.el-button.is-disabled
{
.auction-bid-dialog
.el-message-box__btns
{
--el-button-bg-color
:
#d1d5db
!important
;
/* gray-300 */
padding
:
12px
24px
20px
;
--el-button-text-color
:
#6b7280
!important
;
/* gray-500 */
background
:
#d1d5db
!important
;
/* fallback */
color
:
#6b7280
!important
;
/* fallback */
box-shadow
:
none
!important
;
cursor
:
not-allowed
!important
;
transform
:
none
!important
;
}
}
.bid-btn.el-button.is-disabled
:hover
{
transform
:
none
!important
;
.auction-bid-dialog
.el-message-box__btns
.el-button--primary
{
box-shadow
:
none
!important
;
background
:
linear-gradient
(
to
right
,
#6366f1
,
#8b5cf6
);
background
:
#d1d5db
!important
;
border
:
none
;
color
:
#6b7280
!important
;
border-radius
:
8px
;
padding
:
8px
24px
;
}
.auction-bid-dialog
.el-message-box__btns
.el-button--primary
:hover
{
opacity
:
0.9
;
}
.auction-bid-dialog
.el-message-box__btns
.el-button
:not
(
.el-button--primary
)
{
border-radius
:
8px
;
padding
:
8px
24px
;
}
.auction-bid-dialog
{
border-radius
:
16px
!important
;
overflow
:
hidden
;
}
.auction-bid-dialog
.el-message-box__status
{
display
:
none
!important
;
}
}
</
style
>
</
style
>
src/views/backend/settingsMenu/dailyLotteryManage/components/lotteryConfigDialog.vue
View file @
76422e6d
...
@@ -13,6 +13,15 @@
...
@@ -13,6 +13,15 @@
/>
/>
</el-form-item>
</el-form-item>
<el-form-item
label=
"自动关闭"
prop=
"autoCloseWeekend"
>
<el-form-item
label=
"自动关闭"
prop=
"autoCloseWeekend"
>
<!-- 加一个tips -->
<template
#
label
>
<div
class=
"flex items-center gap-1"
>
<span>
自动关闭
</span>
<el-tooltip
content=
"如果开启,则会在周末自动关闭抽奖"
placement=
"top"
>
<el-icon
size=
"16"
><IEpInfoFilled
/></el-icon>
</el-tooltip>
</div>
</
template
>
<el-switch
<el-switch
v-model=
"form.autoCloseWeekend"
v-model=
"form.autoCloseWeekend"
:active-value=
"1"
:active-value=
"1"
...
...
src/views/homePage/askTab/index.vue
View file @
76422e6d
...
@@ -17,93 +17,79 @@
...
@@ -17,93 +17,79 @@
<div
v-loading=
"loading"
v-if=
"list.length"
>
<div
v-loading=
"loading"
v-if=
"list.length"
>
<!-- 问题列表 -->
<!-- 问题列表 -->
<div
class=
"space-y-4"
>
<div
class=
"space-y-4"
>
<
el-card
<
div
v-for=
"(item, index) in list"
v-for=
"(item, index) in list"
:key=
"item.id"
:key=
"item.id"
class=
"question-card !rounded-lg mb-4 transition-all duration-300 relative"
class=
"relative group bg-white rounded-lg p-5 cursor-pointer transition-all duration-300 hover:shadow-lg hover:shadow-gray-100 border border-gray-100 hover:border-gray-200 mb-3 sm:mb-4"
shadow=
"hover"
>
>
<div
<!-- 推荐标签 -->
v-if=
"item.isRecommend"
<div
v-if=
"item.isRecommend"
class=
"absolute left-0 top-5"
>
class=
"absolute top-0 left-0 w-13 h-6 bg-#FFF9B9 flex items-center justify-center border-2px border-solid border-#f4f0eb rounded-tl-lg rounded-br-lg"
<div
>
class=
"h-5.5 pl-2 pr-2.5 flex items-center gap-1 bg-gradient-to-r from-#6366f1 to-#818cf8 rounded-r-full text-white text-11px font-medium shadow-sm"
<img
class=
"w-6"
src=
"@/assets/img/culture/recommend.png"
alt=
""
/>
>
<div
class=
"text-12px text-#000 line-height-12px"
>
推荐
</div>
<svg
viewBox=
"0 0 16 16"
class=
"w-3 h-3 fill-current"
>
<path
d=
"M8 1.3l2 4.1 4.5.7-3.2 3.1.8 4.5L8 11.5l-4.1 2.2.8-4.5L1.5 6.1l4.5-.7z"
/>
</svg>
推荐
</div>
</div>
</div>
<!-- 问题标题 -->
<h2
<h2
class=
"text-xl line-clamp-1 font-semibold text-gray-900 mb-2 leading-relaxed cursor-pointer hover:text-blue-600 transition-colors"
class=
"text-xl line-clamp-1 font-semibold text-gray-900 mb-3 leading-tight hover:text-blue-600 transition-colors"
:class=
"
{ 'pl-14': item.isRecommend }"
@click="openNewPage(`/questionDetail/${item.id}`)"
@click="openNewPage(`/questionDetail/${item.id}`)"
>
>
{{
item
.
title
}}
{{
item
.
title
}}
</h2>
</h2>
<div
class=
"flex gap-4 mb-2"
>
<!-- 问吧暂时先不展示图片 -->
<div
class=
"mb-3"
>
<!--
<el-image
<p
v-if=
"item.faceUrl && !item.cultureCommentListVo?.hiddenName"
:ref=
"(e) => (contentRefList[index] = e as HTMLElement)"
:src=
"item.faceUrl"
class=
"text-gray-600 text-sm sm:text-base leading-relaxed transition-all duration-300"
fit=
"cover"
:class=
"
{ 'line-clamp-3': !item.isExpand }"
class=
"w-50 h-25 rounded-lg"
>
/>
-->
<template
v-if=
"item.cultureCommentListVo?.hiddenName"
>
<!-- 问题内容 -->
{{
item
.
cultureCommentListVo
?.
hiddenName
}}
:
<div>
<span
v-html=
"parseEmoji(item.cultureCommentListVo?.content)"
></span>
<p
</
template
>
:ref=
"(e) => (contentRefList[index] = e as HTMLElement)"
<
template
v-else
>
class=
"text-gray-600 text-base leading-relaxed transition-all duration-300"
<span
v-html=
"parseEmoji(item.content)"
></span>
:class=
"
{ 'line-clamp-3': !item.isExpand }"
</
template
>
>
</p>
<!-- 如果有评论的话 就展示 最热的 没有的话 说明没有评论 就展示内容 -->
<div
class=
"flex justify-end"
v-if=
"isOverThreeLine(index)"
>
<template
v-if=
"item.cultureCommentListVo?.hiddenName"
>
<el-button
@
click
.
stop=
"handleExpand(item)"
type=
"primary"
text
size=
"small"
>
{{
item
.
cultureCommentListVo
?.
hiddenName
}}
:
{{ item.isExpand ? '收起' : '阅读全文' }}
<span
v-html=
"parseEmoji(item.cultureCommentListVo?.content)"
></span>
<el-icon
class=
"ml-1"
:class=
"{ 'rotate-180': item.isExpand }"
>
</
template
>
<IEpArrowDown
/>
<
template
v-else
>
</el-icon>
<p
v-html=
"parseEmoji(item.content)"
></p>
</el-button>
</
template
>
</p>
<!-- 展开/收起按钮 靠右边布局 -->
<div
class=
"flex justify-end"
>
<el-button
v-if=
"isOverThreeLine(index)"
@
click
.
stop=
"handleExpand(item)"
type=
"primary"
text
size=
"small"
class=
"text-blue-500"
>
{{ item.isExpand ? '收起' : '阅读全文' }}
<el-icon
class=
"ml-1"
:class=
"{ 'rotate-180': item.isExpand }"
>
<IEpArrowDown
/>
</el-icon>
</el-button>
</div>
</div>
</div>
</div>
</div>
<!-- 底部信息栏 -->
<div
class=
"flex items-center justify-between border-t border-gray-100"
>
<div
class=
"flex items-center justify-between pt-3 border-t border-gray-100/80"
>
<!-- 左侧:发布人信息 -->
<div
class=
"flex items-center gap-2 xl:gap-3 flex-wrap"
>
<div
class=
"flex items-center gap-2 lg:gap-4"
>
<div
class=
"flex items-center gap-2"
>
<div
class=
"flex items-center gap-2"
>
<span
class=
"text-orange-500 text-sm font-medium hidden lg:block"
>
发布人
</span>
<el-avatar
:size=
"22"
:src=
"item.showAvatar"
/>
<div
class=
"flex items-center gap-2"
>
<span
class=
"text-sm text-gray-600"
>
{{ item.showName }}
</span>
<el-avatar
:size=
"20"
:src=
"item.showAvatar"
>
</el-avatar>
<span
class=
"text-sm text-gray-700 font-medium"
>
{{ item.showName }}
</span>
</div>
</div>
</div>
<span
class=
"text-xs text-gray-400 hidden sm:inline"
>
{{
<span
class=
"text-xs text-gray-400"
>
{{
dayjs(item.createTime * 1000).format('YYYY-MM-DD HH:mm')
dayjs(item.createTime * 1000).format('YYYY-MM-DD HH:mm')
}}
</span>
}}
</span>
<div
class=
"hidden sm:block w-1 h-1 bg-gray-300 rounded-full"
></div>
<!-- 操作按钮组 -->
<div
class=
"flex items-center gap-1"
>
<div
class=
"flex items-center"
>
<el-button
<el-button
size=
"small"
size=
"small"
plain
plain
:class=
"{ 'opacity-50': item.hasAddQuestion }"
class=
"rounded-lg"
:class=
"{
'!text-blue-500 !border-blue-200 !bg-blue-50': item.hasAddQuestion,
}"
@
click
.
stop=
"handleAddQuestion(item)"
@
click
.
stop=
"handleAddQuestion(item)"
>
>
<el-icon>
<el-icon
class=
"mr-0.5"
>
<IEpCircleCheckFilled
v-show=
"item.hasAddQuestion"
/>
<IEpCircleCheckFilled
v-show=
"item.hasAddQuestion"
/>
<IEpPlus
v-show=
"!item.hasAddQuestion"
/>
<IEpPlus
v-show=
"!item.hasAddQuestion"
/>
</el-icon>
</el-icon>
...
@@ -113,62 +99,33 @@
...
@@ -113,62 +99,33 @@
<el-button
<el-button
size=
"small"
size=
"small"
plain
plain
:class=
"{ 'opacity-50': item.hasCollect }"
class=
"rounded-lg"
:class=
"{ '!text-amber-500 !border-amber-200 !bg-amber-50': item.hasCollect }"
@
click
.
stop=
"handleCollect(item)"
@
click
.
stop=
"handleCollect(item)"
>
>
<el-icon>
<el-icon
class=
"mr-0.5"
>
<IEpStarFilled
v-show=
"item.hasCollect"
/>
<IEpStarFilled
v-show=
"item.hasCollect"
/>
<IEpStar
v-show=
"!item.hasCollect"
/>
<IEpStar
v-show=
"!item.hasCollect"
/>
</el-icon>
</el-icon>
{{ item.hasCollect ? '已关注' : '关注' }}
{{ item.hasCollect ? '已关注' : '关注' }}
</el-button>
</el-button>
<!-- 回答按钮保持不变 -->
<el-button
<!-- 当前最热评论的评论有几条 -->
size=
"small"
<el-button
size=
"small"
plain
@
click
.
stop=
"handleComment(item, index)"
>
plain
<el-icon><IEpEdit
/></el-icon>
class=
"rounded-lg"
@
click
.
stop=
"handleComment(item, index)"
>
<el-icon
class=
"mr-0.5"
><IEpEdit
/></el-icon>
<
template
v-if=
"item.cultureCommentListVo?.childNum"
>
<
template
v-if=
"item.cultureCommentListVo?.childNum"
>
{{
item
.
cultureCommentListVo
?.
childNum
}}
条评论
{{
item
.
cultureCommentListVo
?.
childNum
}}
条评论
</
template
>
</
template
>
<
template
v-else
>
<
template
v-else
>
写评论
</
template
>
<span>
写评论
</span>
</
template
>
</el-button>
</el-button>
<ActionMore
class=
"ml-
4
"
:articleDetail=
"item"
/>
<ActionMore
class=
"ml-
1
"
:articleDetail=
"item"
/>
</div>
</div>
</div>
</div>
<!-- 右侧:统计信息 -->
<div
class=
"flex items-center"
>
<!-- 浏览量 -->
<!-- <el-button text class="flex items-center gap-2 text-gray-500">
<el-icon><IEpView /></el-icon>
<span class="text-sm">{{ item.viewCount || 0 }}</span>
</el-button> -->
<!-- 收藏 -->
<!-- <el-button
text
class="flex items-center gap-2 text-gray-500 transition-colors"
@click.stop="handleCollect(item)"
>
<el-icon :color="item.hasCollect ? '#409EFF' : '#999'"><IEpStar /></el-icon>
<span class="text-sm" :class="{ 'text-blue-500': item.hasCollect }">{{
item.collectionCount || 0
}}</span>
</el-button> -->
<!-- 评论 -->
<!-- <el-button
text
class="flex items-center gap-2 text-gray-500 transition-colors"
@click.stop="handleComment(item, index)"
>
<el-icon><IEpChatDotRound /></el-icon>
<span class="text-sm">{{ item.cultureCommentListVo?.childNum || 0 }}</span>
</el-button> -->
</div>
</div>
</div>
<Transition
name=
"fadeCommentBox"
mode=
"out-in"
>
<Transition
name=
"fadeCommentBox"
mode=
"out-in"
>
<Comment
<Comment
...
@@ -184,7 +141,7 @@
...
@@ -184,7 +141,7 @@
@
commentSuccess=
"() => handleCommentSuccess(item)"
@
commentSuccess=
"() => handleCommentSuccess(item)"
/>
/>
</Transition>
</Transition>
</
el-card
>
</
div
>
</div>
</div>
<!-- 底部分页 -->
<!-- 底部分页 -->
<div
class=
"bottom-pagination backdrop-blur-8 border-t border-gray-200"
>
<div
class=
"bottom-pagination backdrop-blur-8 border-t border-gray-200"
>
...
...
src/views/homePage/homeTab/components/recommendList.vue
View file @
76422e6d
...
@@ -5,27 +5,30 @@
...
@@ -5,27 +5,30 @@
<div
<div
v-for=
"item in list"
v-for=
"item in list"
:key=
"item.id"
:key=
"item.id"
class=
"relative group bg-white rounded-lg p-
6
cursor-pointer transition-all duration-300 hover:shadow-lg hover:shadow-gray-100 hover:-translate-y-1 border border-gray-100 hover:border-gray-200 mb-3 sm:mb-4"
class=
"relative group bg-white rounded-lg p-
4
cursor-pointer transition-all duration-300 hover:shadow-lg hover:shadow-gray-100 hover:-translate-y-1 border border-gray-100 hover:border-gray-200 mb-3 sm:mb-4"
@
click=
"jumpToArticleDetailPage(
{ type: item.type, id: item.id })"
@
click=
"jumpToArticleDetailPage(
{ type: item.type, id: item.id })"
>
>
<div
class=
"flex gap-3 justify-between"
>
<!-- 推荐标签 -->
<div
v-if=
"item.isRecommend"
class=
"absolute left-0 top-5"
>
<div
<div
v-if=
"item.isRecommend"
class=
"h-5.5 pl-2 pr-2.5 flex items-center gap-1 bg-gradient-to-r from-#6366f1 to-#818cf8 rounded-r-full text-white text-11px font-medium shadow-sm"
class=
"absolute top-0 left-0 w-13 h-6 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=
""
/>
<svg
viewBox=
"0 0 16 16"
class=
"w-3 h-3 fill-current"
>
<div
class=
"text-12px text-#000 line-height-12px"
>
推荐
</div>
<path
d=
"M8 1.3l2 4.1 4.5.7-3.2 3.1.8 4.5L8 11.5l-4.1 2.2.8-4.5L1.5 6.1l4.5-.7z"
/>
</svg>
推荐
</div>
</div>
<!-- 内容区域 -->
</div>
<div
class=
"flex gap-3 justify-between"
>
<div
class=
"flex-1 min-w-0 flex flex-col justify-between h-24"
>
<div
class=
"flex-1 min-w-0 flex flex-col justify-between h-24"
>
<!-- 标题 -->
<h2
<h2
class=
"text-xl font-semibold text-gray-900 line-clamp-1 group-hover:text-blue-600 transition-colors duration-200 leading-tight"
class=
"text-xl font-semibold text-gray-900 line-clamp-1 group-hover:text-blue-600 transition-colors duration-200 leading-tight"
:class=
"
{ 'pl-12': item.isRecommend }"
>
>
{{
item
.
title
}}
{{
item
.
title
}}
</h2>
</h2>
<!-- 内容摘要 -->
<div
v-if=
"!item.content?.includes('
</
')"
class
="my-2
space-y-1"
>
<div
v-if=
"!item.content?.includes('
</
')"
class
="my-2
space-y-1"
>
<p
<p
class=
"text-gray-600 text-sm sm:text-base leading-relaxed line-clamp-1 break-all"
class=
"text-gray-600 text-sm sm:text-base leading-relaxed line-clamp-1 break-all"
...
@@ -34,14 +37,11 @@
...
@@ -34,14 +37,11 @@
</p>
</p>
</div>
</div>
<!-- 统计信息 -->
<div
class=
"flex items-center gap-2 xl:gap-4 text-gray-500 text-xs lg:text-sm"
>
<div
class=
"flex items-center gap-2 xl:gap-4 text-gray-500 text-xs lg:text-sm"
>
<!-- 发布人名称和头像 -->
<div
class=
"flex items-center gap-2"
>
<div
class=
"flex items-center gap-2"
>
<el-avatar
:size=
"24"
:src=
"item.showAvatar"
/>
<el-avatar
:size=
"24"
:src=
"item.showAvatar"
/>
<span
class=
"text-sm text-gray-500"
>
{{
item
.
showName
}}
</span>
<span
class=
"text-sm text-gray-500"
>
{{
item
.
showName
}}
</span>
</div>
</div>
<!-- 时间 -->
<span
class=
"text-gray-500 font-medium ml-0"
>
<span
class=
"text-gray-500 font-medium ml-0"
>
<span
class=
"hidden sm:inline"
>
{{
<span
class=
"hidden sm:inline"
>
{{
dayjs
(
item
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm'
)
dayjs
(
item
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm'
)
...
@@ -50,7 +50,6 @@
...
@@ -50,7 +50,6 @@
<span
class=
"text-sm text-gray-500"
>
{{
<span
class=
"text-sm text-gray-500"
>
{{
articleTypeListOptions
.
find
((
i
)
=>
i
.
value
===
item
.
type
)?.
label
articleTypeListOptions
.
find
((
i
)
=>
i
.
value
===
item
.
type
)?.
label
}}
</span>
}}
</span>
<!-- 分隔符 -->
<div
class=
"hidden sm:block w-1 h-1 bg-gray-300 rounded-full"
></div>
<div
class=
"hidden sm:block w-1 h-1 bg-gray-300 rounded-full"
></div>
<div
class=
"flex items-center gap-1 hover:text-blue-500 transition-colors"
>
<div
class=
"flex items-center gap-1 hover:text-blue-500 transition-colors"
>
<el-icon
class=
"text-sm"
><IEpView
/></el-icon>
<el-icon
class=
"text-sm"
><IEpView
/></el-icon>
...
@@ -71,7 +70,6 @@
...
@@ -71,7 +70,6 @@
</div>
</div>
</div>
</div>
<!-- 图片区域 -->
<div
v-show=
"item.faceUrl"
class=
"relative flex-shrink-0 w-30 h-20 xl:w-36 xl:h-24"
>
<div
v-show=
"item.faceUrl"
class=
"relative flex-shrink-0 w-30 h-20 xl:w-36 xl:h-24"
>
<el-image
<el-image
:src=
"item.faceUrl + '?x-oss-process=image/format,webp'"
:src=
"item.faceUrl + '?x-oss-process=image/format,webp'"
...
@@ -81,7 +79,6 @@
...
@@ -81,7 +79,6 @@
class=
"w-full h-full object-cover rounded-lg sm:rounded-lg group-hover:scale-105 transition-transform duration-300"
class=
"w-full h-full object-cover rounded-lg sm:rounded-lg group-hover:scale-105 transition-transform duration-300"
loading=
"lazy"
loading=
"lazy"
/>
/>
<!-- 图片遮罩效果 -->
<div
<div
class=
"absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-5 rounded-lg sm:rounded-lg transition-all duration-300"
class=
"absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-5 rounded-lg sm:rounded-lg transition-all duration-300"
></div>
></div>
...
@@ -94,12 +91,10 @@
...
@@ -94,12 +91,10 @@
<div
class=
"bottom-pagination backdrop-blur-8 border-t border-gray-200"
>
<div
class=
"bottom-pagination backdrop-blur-8 border-t border-gray-200"
>
<div
class=
"max-w-7xl mx-auto py-4"
>
<div
class=
"max-w-7xl mx-auto py-4"
>
<div
class=
"flex items-center justify-between"
>
<div
class=
"flex items-center justify-between"
>
<!-- 左侧:回到顶部按钮 -->
<div
class=
"left"
>
<div
class=
"left"
>
<ScrollTopComp
/>
<ScrollTopComp
/>
</div>
</div>
<!-- 右侧:分页器 -->
<div
class=
"right"
>
<div
class=
"right"
>
<div
<div
class=
"pagination-wrapper bg-white rounded-lg shadow-sm border border-gray-100 p-2"
class=
"pagination-wrapper bg-white rounded-lg shadow-sm border border-gray-100 p-2"
...
...
src/views/homePage/yaTab/components/columnList.vue
View file @
76422e6d
...
@@ -5,94 +5,91 @@
...
@@ -5,94 +5,91 @@
<div
<div
v-for=
"(item, index) in list"
v-for=
"(item, index) in list"
:key=
"index"
:key=
"index"
class=
"bg-white rounded-
lg shadow-sm mb-6 overflow-hidden
"
class=
"bg-white rounded-
xl shadow-sm mb-6 overflow-hidden border border-gray-100
"
:style=
"
{ '--dynamic-color': item.color }"
:style=
"
{ '--dynamic-color': item.color }"
>
>
<!-- 专栏标题栏 -->
<div
<div
class=
"flex items-center justify-between p
r-4 pl-4 pt-2 pb-2 bg-green-50 border-b border-green-100
"
class=
"flex items-center justify-between p
x-5 py-3
"
:style=
"
{ backgroundColor: item.color
, '--dynamic-color': item.color
}"
:style=
"
{ backgroundColor: item.color }"
>
>
<h3
class=
"text-
lg font-medium text-gray-800 flex items-center
"
>
<h3
class=
"text-
base font-semibold text-gray-800 flex items-center gap-2
"
>
<span
class=
"w-1 h-5
mr-2 bg-#444
"
></span>
<span
class=
"w-1 h-5
rounded-full bg-gray-700/60
"
></span>
{{
item
.
title
}}
{{
item
.
title
}}
</h3>
</h3>
<div
<div
class=
"flex items-center cursor-pointer"
class=
"flex items-center cursor-pointer
text-13px text-gray-500 hover:text-indigo-500 transition-colors duration-200
"
@
click=
"
@
click=
"
router.push(
{
router.push(
{
path: `/columnSearchList/${item.id}`,
path: `/columnSearchList/${item.id}`,
query: {
query: { columnTitle: item.title },
columnTitle: item.title,
},
})
})
"
"
>
>
<span
class=
"mr-1 text-14px color-#606266"
>
查看更多 >>
</span
>
查看更多 >
>
</div>
</div>
</div>
</div>
<div
class=
"p-4"
>
<!-- 内容区 -->
<div
class=
"p-5"
>
<div
<div
v-if=
"item.yaColumnVoList.length"
v-if=
"item.yaColumnVoList.length"
class=
"grid grid-cols-1
grid-cols-2 lg:grid-cols-3 gap-4
"
class=
"grid grid-cols-1
sm:grid-cols-2 lg:grid-cols-3 gap-5
"
>
>
<div
<div
v-for=
"i in item.yaColumnVoList"
v-for=
"i in item.yaColumnVoList"
:key=
"i.articleId"
:key=
"i.articleId"
class=
"group cursor-pointer"
class=
"group cursor-pointer
rounded-lg overflow-hidden border border-transparent hover:border-gray-200 hover:shadow-md transition-all duration-300
"
@
click=
"jumpToArticleDetailPage(
{ type: i.type, id: i.articleId })"
@
click=
"jumpToArticleDetailPage(
{ type: i.type, id: i.articleId })"
>
>
<div
class=
"relative mb-3 overflow-hidden rounded-lg"
>
<!-- 封面图 -->
<div
class=
"relative overflow-hidden"
>
<img
<img
:src=
"i.faceUrl"
:src=
"i.faceUrl"
class=
"w-full aspect-[5/3] object-cover group-hover:scale-105 transition-transform duration-300"
class=
"w-full aspect-[5/3] object-cover group-hover:scale-105 transition-transform duration-300"
/>
/>
<!-- 推荐角标 -->
<div
<div
v-if=
"i.isRecommend"
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"
class=
"absolute top-
0 left-0 w-15 h-7
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=
""
/>
<img
class=
"w-6"
src=
"@/assets/img/culture/recommend.png"
alt=
""
/>
<div
class=
"text-12px text-#000 line-height-12px"
>
推荐
</div>
<div
class=
"text-12px text-#000 line-height-12px"
>
推荐
</div>
</div>
</div>
<!-- 底部渐变遮罩 -->
<div
class=
"absolute inset-x-0 bottom-0 h-12 bg-gradient-to-t from-black/30 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300"
></div>
</div>
</div>
<!-- 屏幕变小 标题变小 -->
<div
<!-- 文字信息 -->
class=
"font-medium text-gray-800 mb-2 transition-colors line-clamp-1 text-sm xl:text-lg"
<div
class=
"p-3"
>
>
<div
{{
i
.
title
}}
class=
"font-semibold text-gray-800 mb-2.5 line-clamp-1 text-base group-hover:text-indigo-600 transition-colors duration-200"
</div>
>
<!-- 因为是富文本 暂时不显示 -->
{{
i
.
title
}}
<!--
<p
class=
"text-sm text-gray-500 mb-3 line-clamp-1"
>
{{
i
.
content
}}
</p>
-->
<div
class=
"flex items-center justify-between text-xs text-gray-500"
>
<div
class=
"flex items-center gap-2"
>
<span
class=
"flex items-center"
>
<el-icon
class=
"mr-1"
>
<IEpView
/>
</el-icon>
{{
i
.
viewCount
}}
</span>
<span
class=
"flex items-center"
>
<el-icon
class=
"mr-1"
>
<IEpChatDotRound
/>
</el-icon>
{{
i
.
replyCount
}}
</span>
<span
class=
"flex items-center"
>
<el-icon
class=
"mr-1"
>
<IEpStar
/>
</el-icon>
{{
i
.
collectCount
}}
</span>
</div>
</div>
<span>
<div
class=
"flex items-center justify-between text-xs text-gray-500"
>
{{
<div
class=
"flex items-center gap-3"
>
<span
class=
"flex items-center gap-0.5"
>
<el-icon><IEpView
/></el-icon>
{{
i
.
viewCount
}}
</span>
<span
class=
"flex items-center gap-0.5"
>
<el-icon><IEpChatDotRound
/></el-icon>
{{
i
.
replyCount
}}
</span>
<span
class=
"flex items-center gap-0.5"
>
<el-icon><IEpStar
/></el-icon>
{{
i
.
collectCount
}}
</span>
</div>
<span
class=
"text-gray-400"
>
{{
smallerThanXl
smallerThanXl
?
dayjs
(
i
.
createTime
*
1000
).
format
(
'YYYY-MM-DD'
)
?
dayjs
(
i
.
createTime
*
1000
).
format
(
'YYYY-MM-DD'
)
:
dayjs
(
i
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm:ss'
)
:
dayjs
(
i
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm:ss'
)
}}
}}
</span>
</
span
>
</
div
>
</div>
</div>
</div>
</div>
</div>
</div>
...
@@ -151,7 +148,6 @@ import dayjs from 'dayjs'
...
@@ -151,7 +148,6 @@ import dayjs from 'dayjs'
import
{
useRouter
}
from
'vue-router'
import
{
useRouter
}
from
'vue-router'
import
{
jumpToArticleDetailPage
}
from
'@/utils'
import
{
jumpToArticleDetailPage
}
from
'@/utils'
import
{
breakpointsTailwind
,
useBreakpoints
}
from
'@vueuse/core'
import
{
breakpointsTailwind
,
useBreakpoints
}
from
'@vueuse/core'
console
.
log
(
breakpointsTailwind
,
'breakpointsTailwind'
)
const
breakpoints
=
useBreakpoints
(
breakpointsTailwind
)
const
breakpoints
=
useBreakpoints
(
breakpointsTailwind
)
const
smallerThanXl
=
breakpoints
.
smaller
(
'xl'
)
const
smallerThanXl
=
breakpoints
.
smaller
(
'xl'
)
...
...
src/views/homePage/yaTab/components/interviewList.vue
View file @
76422e6d
...
@@ -5,46 +5,39 @@
...
@@ -5,46 +5,39 @@
<div
<div
v-for=
"(item, index) in list"
v-for=
"(item, index) in list"
:key=
"index"
:key=
"index"
class=
"bg-white rounded-
lg shadow-sm mb-6 overflow-hidden
"
class=
"bg-white rounded-
xl shadow-sm mb-6 overflow-hidden border border-gray-100
"
:style=
"
{ '--dynamic-color': item.color }"
:style=
"
{ '--dynamic-color': item.color }"
>
>
<!-- 专栏标题栏 -->
<div
<div
class=
"flex items-center justify-between p
r-4 pl-4 pt-2 pb-2 bg-green-50 border-b border-green-100
"
class=
"flex items-center justify-between p
x-5 py-3
"
:style=
"
{ backgroundColor: item.color
, '--dynamic-color': item.color
}"
:style=
"
{ backgroundColor: item.color }"
>
>
<h3
class=
"text-
lg font-medium text-gray-800 flex items-center
"
>
<h3
class=
"text-
base font-semibold text-gray-800 flex items-center gap-2
"
>
<span
class=
"w-1 h-5
mr-2 bg-#444
"
></span>
<span
class=
"w-1 h-5
rounded-full bg-gray-700/60
"
></span>
{{
item
.
title
}}
{{
item
.
title
}}
</h3>
</h3>
<div
class=
"flex items-center cursor-pointer hover:text-[var(--dynamic-color)]"
@
click=
"
router.push(
{
path: '/searchPage',
query: {
type: ArticleTypeEnum.INTERVIEW,
},
})
"
>
</div>
</div>
</div>
<div
class=
"p-4"
>
<!-- 内容区 -->
<div
class=
"p-5"
>
<div
<div
v-if=
"item.yaColumnVoList.length"
v-if=
"item.yaColumnVoList.length"
class=
"grid grid-cols-1
grid-cols-2 lg:grid-cols-3 gap-4
"
class=
"grid grid-cols-1
sm:grid-cols-2 lg:grid-cols-3 gap-5
"
>
>
<div
<div
v-for=
"i in item.yaColumnVoList"
v-for=
"i in item.yaColumnVoList"
:key=
"i.articleId"
:key=
"i.articleId"
class=
"group cursor-pointer"
class=
"group cursor-pointer
rounded-lg overflow-hidden border border-transparent hover:border-gray-200 hover:shadow-md transition-all duration-300
"
@
click=
"jumpToArticleDetailPage(
{ type: i.type, id: i.articleId })"
@
click=
"jumpToArticleDetailPage(
{ type: i.type, id: i.articleId })"
>
>
<div
class=
"relative mb-3 overflow-hidden rounded-lg"
>
<!-- 封面图 -->
<div
class=
"relative overflow-hidden"
>
<img
<img
:src=
"i.faceUrl"
:src=
"i.faceUrl"
class=
"w-full aspect-[5/3] object-cover group-hover:scale-105 transition-transform duration-300"
class=
"w-full aspect-[5/3] object-cover group-hover:scale-105 transition-transform duration-300"
/>
/>
<!-- 推荐角标 -->
<div
<div
v-if=
"i.isRecommend"
v-if=
"i.isRecommend"
class=
"absolute top-0 left-0 w-15 h-7 bg-#FFF9B9 flex items-center justify-center border-2px border-solid border-#f4f0eb rounded-tl-lg rounded-br-lg"
class=
"absolute top-0 left-0 w-15 h-7 bg-#FFF9B9 flex items-center justify-center border-2px border-solid border-#f4f0eb rounded-tl-lg rounded-br-lg"
...
@@ -52,42 +45,40 @@
...
@@ -52,42 +45,40 @@
<img
class=
"w-6"
src=
"@/assets/img/culture/recommend.png"
alt=
""
/>
<img
class=
"w-6"
src=
"@/assets/img/culture/recommend.png"
alt=
""
/>
<div
class=
"text-12px text-#000 line-height-12px"
>
推荐
</div>
<div
class=
"text-12px text-#000 line-height-12px"
>
推荐
</div>
</div>
</div>
<!-- 底部渐变遮罩 -->
<div
class=
"absolute inset-x-0 bottom-0 h-12 bg-gradient-to-t from-black/30 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300"
></div>
</div>
</div>
<div
class=
"font-medium text-gray-800 mb-2 transition-colors line-clamp-1 text-sm xl:text-lg"
<!-- 文字信息 -->
>
<div
class=
"p-3"
>
{{
i
.
title
}}
<div
</div>
class=
"font-semibold text-gray-800 mb-2.5 line-clamp-1 text-base group-hover:text-indigo-600 transition-colors duration-200"
<!-- 因为是富文本 暂时不显示 -->
>
<!--
<p
class=
"text-xs text-gray-500 mb-3 line-clamp-1"
>
{{
i
.
title
}}
{{
i
.
content
}}
</div>
</p>
-->
<div
class=
"flex items-center justify-between text-xs text-gray-500"
>
<div
class=
"flex items-center justify-between text-xs text-gray-400"
>
<div
class=
"flex items-center gap-3"
>
<div
class=
"flex items-center space-x-4"
>
<span
class=
"flex items-center gap-0.5"
>
<span
class=
"flex items-center"
>
<el-icon><IEpView
/></el-icon>
<el-icon
class=
"mr-1"
>
{{
i
.
viewCount
}}
<IEpView
/>
</span>
</el-icon>
<span
class=
"flex items-center gap-0.5"
>
{{
i
.
viewCount
}}
<el-icon><IEpChatDotRound
/></el-icon>
</span>
{{
i
.
replyCount
}}
<span
class=
"flex items-center"
>
</span>
<el-icon
class=
"mr-1"
>
<span
class=
"flex items-center gap-0.5"
>
<IEpChatDotRound
/>
<el-icon><IEpStar
/></el-icon>
</el-icon>
{{
i
.
collectCount
}}
{{
i
.
replyCount
}}
</span>
</span>
</div>
<span
class=
"flex items-center"
>
<span
class=
"text-gray-400"
>
{{
<el-icon
class=
"mr-1"
>
smallerThanXl
<IEpStar
/>
?
dayjs
(
i
.
createTime
*
1000
).
format
(
'YYYY-MM-DD'
)
</el-icon>
:
dayjs
(
i
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm:ss'
)
{{
i
.
collectCount
}}
}}
</span>
</span>
</div>
</div>
<span>
{{
smallerThanXl
?
dayjs
(
i
.
createTime
*
1000
).
format
(
'YYYY-MM-DD'
)
:
dayjs
(
i
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm:ss'
)
}}
</span>
</div>
</div>
</div>
</div>
</div>
</div>
...
@@ -142,14 +133,12 @@
...
@@ -142,14 +133,12 @@
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
{
getInterviewList
}
from
'@/api'
import
{
getInterviewList
}
from
'@/api'
import
{
usePageSearch
,
useScrollTop
}
from
'@/hooks'
import
{
usePageSearch
,
useScrollTop
}
from
'@/hooks'
import
{
TABS_REF_KEY
,
ArticleTypeEnum
}
from
'@/constants'
import
{
TABS_REF_KEY
}
from
'@/constants'
import
{
useRouter
}
from
'vue-router'
import
dayjs
from
'dayjs'
import
dayjs
from
'dayjs'
import
{
jumpToArticleDetailPage
}
from
'@/utils'
import
{
jumpToArticleDetailPage
}
from
'@/utils'
import
{
breakpointsTailwind
,
useBreakpoints
}
from
'@vueuse/core'
import
{
breakpointsTailwind
,
useBreakpoints
}
from
'@vueuse/core'
const
breakpoints
=
useBreakpoints
(
breakpointsTailwind
)
const
breakpoints
=
useBreakpoints
(
breakpointsTailwind
)
const
smallerThanXl
=
breakpoints
.
smaller
(
'xl'
)
const
smallerThanXl
=
breakpoints
.
smaller
(
'xl'
)
const
router
=
useRouter
()
const
tabsRef
=
inject
(
TABS_REF_KEY
)
const
tabsRef
=
inject
(
TABS_REF_KEY
)
const
{
handleBackTop
,
ScrollTopComp
}
=
useScrollTop
(
tabsRef
!
)
const
{
handleBackTop
,
ScrollTopComp
}
=
useScrollTop
(
tabsRef
!
)
...
...
src/views/homePage/yaTab/components/practiceList.vue
View file @
76422e6d
...
@@ -101,9 +101,11 @@
...
@@ -101,9 +101,11 @@
</div>
</div>
</div>
</div>
<!-- 内容区域 -->
<!-- 内容区域 -->
<div
class=
"bg-
white rounded-lg shadow-sm
"
>
<div
class=
"bg-
gray-50/80 rounded-lg shadow-sm border border-gray-100
"
>
<!-- 最新标题 -->
<!-- 最新标题 -->
<div
class=
"flex items-center justify-between p-4 border-b border-gray-100"
>
<div
class=
"flex items-center justify-between p-4 bg-white rounded-t-lg border-b border-gray-100"
>
<div
class=
"flex items-center gap-2"
>
<div
class=
"flex items-center gap-2"
>
<div
class=
"w-1 h-6 bg-red-500 rounded"
></div>
<div
class=
"w-1 h-6 bg-red-500 rounded"
></div>
<h2
class=
"text-lg font-medium"
>
<h2
class=
"text-lg font-medium"
>
...
@@ -126,66 +128,59 @@
...
@@ -126,66 +128,59 @@
查看更多 >>
查看更多 >>
</div>
</div>
</div>
</div>
<div
class=
"
divide-y bg-#fff
"
>
<div
class=
"
space-y-3 p-4
"
>
<div
<div
@
click=
"jumpToArticleDetailPage(
{ type: ArticleTypeEnum.PRACTICE, id: item.id })"
v-for=
"item in list"
v-for=
"item in list"
:key=
"item.id"
:key=
"item.id"
class="p-4 hover:bg-gray-50 transition-colors cursor-pointer pl-8"
class=
"group bg-white rounded-lg p-5 cursor-pointer transition-all duration-300 shadow-sm hover:shadow-lg hover:shadow-gray-100 hover:-translate-y-1 border border-gray-100 hover:border-gray-200"
@
click=
"jumpToArticleDetailPage(
{ type: ArticleTypeEnum.PRACTICE, id: item.id })"
>
>
<div
class=
"flex gap-3 items-center h-100%"
style=
"border-bottom: 1.5px solid #ddd"
>
<div
class=
"flex gap-4 justify-between"
>
<!-- 左侧内容 -->
<div
class=
"flex-1 min-w-0"
>
<div
class=
"flex-1"
>
<h2
<h1
class=
"font-medium text-gray-800 mb-2 leading-relaxed line-clamp-1 text-lg"
>
class=
"text-lg font-semibold text-gray-900 line-clamp-1 group-hover:text-blue-600 transition-colors duration-200 mb-2"
>
{{
item
.
title
}}
{{
item
.
title
}}
</h
1
>
</h
2
>
<!-- 带图片的内容 -->
<div
class=
"flex gap-3 mb-3"
>
<div
class=
"flex gap-3 mb-2 align-center"
>
<el-image
<img
v-if=
"item.faceUrl"
v-if=
"item.faceUrl"
:src=
"item.faceUrl"
:src=
"item.faceUrl"
:alt=
"item.title"
:alt=
"item.title"
class=
"w-40 h-25 object-cover rounded-lg flex-shrink-0"
fit=
"cover"
:lazy=
"true"
class=
"w-36 h-22 rounded-lg flex-shrink-0 object-cover group-hover:scale-105 transition-transform duration-300 overflow-hidden"
loading=
"lazy"
/>
/>
<div
class=
"flex-1 mr-4"
>
<p
class=
"text-gray-500 text-sm leading-relaxed line-clamp-3 flex-1"
>
<div
class=
"text-gray-500 text-base leading-relaxed line-clamp-3"
>
{{
item
.
content
}}
{{
item
.
content
}}
</p>
</div>
</div>
</div>
</div>
<!-- 互动数据 -->
<div
class=
"flex items-center gap-2 xl:gap-4 text-gray-500 text-xs lg:text-sm"
>
<div
class=
"flex items-center gap-5 text-gray-400 text-sm mb-2"
>
<div
class=
"flex items-center gap-2"
>
<div
class=
"flex items-center gap-1"
>
<el-avatar
:size=
"22"
:src=
"item.showAvatar"
/>
<el-icon
class=
"text-sm"
>
<span
class=
"text-sm text-gray-500"
>
{{
item
.
showName
}}
</span>
<IEpView
/>
</el-icon>
<span>
{{
item
.
viewCount
}}
</span>
</div>
</div>
<div
class=
"flex items-center gap-1"
>
<span
class=
"hidden sm:inline text-gray-400"
>
<el-icon
class=
"text-sm"
>
{{
dayjs
(
item
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm'
)
}}
<IEpChatDotRound
/>
</span>
</el-icon>
<div
class=
"hidden sm:block w-1 h-1 bg-gray-300 rounded-full"
></div>
<span>
{{
item
.
replyCount
}}
</span>
<div
class=
"flex items-center gap-1 hover:text-blue-500 transition-colors"
>
<el-icon
class=
"text-sm"
><IEpView
/></el-icon>
<span
class=
"font-medium"
>
{{
item
.
viewCount
}}
</span>
</div>
</div>
<div
class=
"flex items-center gap-1 mr-2"
>
<div
class=
"flex items-center gap-1 hover:text-red-500 transition-colors"
>
<el-icon
class=
"text-sm"
>
<el-icon
class=
"text-sm"
><IEpChatDotRound
/></el-icon>
<IEpStar
/>
<span
class=
"font-medium"
>
{{
item
.
replyCount
}}
</span>
</el-icon>
</div>
<span>
{{
item
.
praiseCount
}}
</span>
<div
class=
"flex items-center gap-1 hover:text-yellow-500 transition-colors"
>
<el-icon
class=
"text-sm"
><IEpStar
/></el-icon>
<span
class=
"font-medium"
>
{{
item
.
praiseCount
}}
</span>
</div>
</div>
<div>
{{
dayjs
(
item
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm'
)
}}
</div>
</div>
</div>
</div>
</div>
<!-- 加一个el-divider -->
<el-divider
class=
"my-1! h-100%!"
direction=
"vertical"
/>
<!-- 右侧头像 -->
<div
class=
"flex flex-col items-center gap-1 flex-shrink-0 pr-8"
>
<el-avatar
:size=
"45"
:src=
"item.showAvatar"
/>
<div
class=
"text-xs text-gray-600 mt-2"
>
{{
item
.
showName
}}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
...
...
src/views/pointsStore/components/exchangeContent.tsx
View file @
76422e6d
...
@@ -17,43 +17,35 @@ export default function ExchangeContent(
...
@@ -17,43 +17,35 @@ export default function ExchangeContent(
{
item
,
modelValue
}:
ExchangeContentProps
,
{
item
,
modelValue
}:
ExchangeContentProps
,
context
:
SetupContext
<
ExchangeContentEvents
>
,
context
:
SetupContext
<
ExchangeContentEvents
>
,
)
{
)
{
const
totalPrice
=
computed
(()
=>
item
.
price
*
(
modelValue
.
num
||
1
))
return
(
return
(
<
div
class=
"exchange-content py-6 px-4"
>
<
div
class=
"py-4"
>
{
/* 商品图片区域 */
}
{
/* 商品信息卡片 */
}
<
div
class=
"flex justify-center mb-8"
>
<
div
class=
"flex gap-4 p-4 bg-gray-50 rounded-xl mb-5"
>
<
div
class=
"relative"
>
<
div
class=
"w-24 h-24 bg-white rounded-xl overflow-hidden shadow-sm shrink-0
<
div
class=
"w-32 h-32 bg-gradient-to-br from-orange-100 to-pink-100 rounded-3xl flex items-center justify-center shadow-lg"
>
flex items-center justify-center p-2"
>
<
div
class=
"w-20 h-20 bg-white rounded-lg flex items-center justify-center shadow-sm"
>
<
img
src=
{
item
.
imageUrl
}
alt=
{
item
.
name
}
<
img
src=
{
item
.
imageUrl
}
alt=
{
item
.
name
}
class=
"w-16 h-16 object-contain"
/>
class=
"max-w-full max-h-full object-contain rounded-lg"
/>
</
div
>
</
div
>
<
div
class=
"flex flex-col justify-center min-w-0 gap-1.5"
>
<
div
class=
"text-base font-semibold text-gray-800 line-clamp-2"
>
{
item
.
name
}
</
div
>
<
div
class=
"flex items-baseline gap-1"
>
<
span
class=
"text-xs text-orange-400"
>
¥
</
span
>
<
span
class=
"text-2xl font-bold text-orange-500"
>
{
item
.
price
}
</
span
>
<
span
class=
"text-xs text-gray-400 ml-1"
>
积分/件
</
span
>
</
div
>
</
div
>
<
div
class=
"
absolute -top-2 -right-2 w-7 h-7 bg-blue-500 rounded-full flex items-center justify-center shadow-md
"
>
<
div
class=
"
text-12px text-gray-400
"
>
<
span
class=
"text-white text-sm font-medium"
>
{
item
.
stock
}
</
span
>
剩余库存:
<
span
class=
"text-gray-600 font-medium"
>
{
item
.
stock
}
</
span
>
件
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
{
/* 商品信息 */
}
{
/* 表单区域 */
}
<
div
class=
"space-y-3 mb-8"
>
<
div
class=
"flex items-center gap-3 px-4"
>
<
div
class=
"w-1.5 h-1.5 bg-gray-400 rounded-full flex-shrink-0"
></
div
>
<
span
class=
"text-gray-600 text-sm min-w-12"
>
名称:
</
span
>
<
span
class=
"font-medium text-gray-900 flex-1"
>
{
item
.
name
}
</
span
>
</
div
>
<
div
class=
"flex items-center gap-3 px-4"
>
<
div
class=
"w-1.5 h-1.5 bg-orange-400 rounded-full flex-shrink-0"
></
div
>
<
span
class=
"text-gray-600 text-sm min-w-12"
>
积分:
</
span
>
<
span
class=
"font-semibold text-orange-500 text-lg"
>
{
item
.
price
}
YA币
</
span
>
</
div
>
</
div
>
{
/* 办公点选择和数量 */
}
{
item
.
itemType
===
ShopGoodsTypeEnum
.
REAL_GOODS
&&
(
{
item
.
itemType
===
ShopGoodsTypeEnum
.
REAL_GOODS
&&
(
<
div
class=
" rounded-lg px-5 mx-2 space-y-4"
>
<
div
class=
"space-y-4 mb-5"
>
{
/* 办公点选择 */
}
<
div
>
<
div
>
<
label
class=
"text-
gray-700 text-sm font-medium mb-2 block"
>
办公点
</
label
>
<
label
class=
"text-
13px text-gray-600 font-medium mb-2 block"
>
配送
办公点
</
label
>
<
el
-
select
<
el
-
select
modelValue=
{
modelValue
.
deliveryInfo
}
modelValue=
{
modelValue
.
deliveryInfo
}
onUpdate
:
modelValue=
{
(
value
:
string
)
=>
onUpdate
:
modelValue=
{
(
value
:
string
)
=>
...
@@ -68,9 +60,8 @@ export default function ExchangeContent(
...
@@ -68,9 +60,8 @@ export default function ExchangeContent(
</
el
-
select
>
</
el
-
select
>
</
div
>
</
div
>
{
/* 数量选择 */
}
<
div
>
<
div
>
<
label
class=
"text-
gray-700 text-sm font-medium mb-2 block"
>
选择
数量
</
label
>
<
label
class=
"text-
13px text-gray-600 font-medium mb-2 block"
>
兑换
数量
</
label
>
<
el
-
input
-
number
<
el
-
input
-
number
min=
{
1
}
min=
{
1
}
max=
{
item
.
stock
}
max=
{
item
.
stock
}
...
@@ -78,12 +69,29 @@ export default function ExchangeContent(
...
@@ -78,12 +69,29 @@ export default function ExchangeContent(
onUpdate
:
modelValue=
{
(
value
:
number
)
=>
onUpdate
:
modelValue=
{
(
value
:
number
)
=>
context
.
emit
(
'update:modelValue'
,
{
...
modelValue
,
num
:
value
})
context
.
emit
(
'update:modelValue'
,
{
...
modelValue
,
num
:
value
})
}
}
class=
"w-full"
class=
"w-full
!
"
controls
-
position=
"right"
controls
-
position=
"right"
/>
/>
</
div
>
</
div
>
</
div
>
</
div
>
)
}
)
}
{
/* 费用汇总 */
}
<
div
class=
"border-t border-dashed border-gray-200 pt-4 mt-4"
>
<
div
class=
"flex items-center justify-between"
>
<
span
class=
"text-sm text-gray-500"
>
合计扣除
{
modelValue
.
num
>
1
&&
(
<
span
class=
"text-gray-400 text-xs ml-1"
>
(
{
item
.
price
}
×
{
modelValue
.
num
}
)
</
span
>
)
}
</
span
>
<
div
class=
"flex items-baseline gap-0.5"
>
<
span
class=
"text-sm text-orange-400"
>
¥
</
span
>
<
span
class=
"text-2xl font-bold text-orange-500"
>
{
totalPrice
.
value
}
</
span
>
<
span
class=
"text-xs text-gray-400 ml-1"
>
积分
</
span
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
)
)
}
}
...
...
src/views/pointsStore/index.vue
View file @
76422e6d
...
@@ -15,30 +15,40 @@
...
@@ -15,30 +15,40 @@
</div>
</div>
<template
v-if=
"virtualGoodsList.length"
>
<template
v-if=
"virtualGoodsList.length"
>
<div
class=
"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4"
>
<div
class=
"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4
xl:grid-cols-5
gap-4"
>
<div
<div
v-for=
"item in virtualGoodsList"
v-for=
"item in virtualGoodsList"
:key=
"item.id"
:key=
"item.id"
class=
"g
roup bg-white rounded-lg p-4 flex flex-col items-center shadow-md transition-all duration-200 cursor-pointer border border-gray-200 hover:border-blue
-300"
class=
"g
oods-card group relative bg-white rounded-xl overflow-hidden cursor-pointer border border-gray-200/80 shadow-sm hover:shadow-lg hover:-translate-y-1 transition-all duration
-300"
@
click=
"onExchangeGoods(item)"
@
click=
"onExchangeGoods(item)"
>
>
<div
<div
class=
"
w-20 h-20 mb-3 flex items-center justify-center bg-blue-50/50 rounded-lg p-2
"
class=
"
aspect-square bg-gradient-to-br from-gray-50 to-gray-100/80 overflow-hidden p-5 flex items-center justify-center
"
>
>
<img
<img
:src=
"item.imageUrl"
:src=
"item.imageUrl"
alt=
""
alt=
""
class=
"
rounded-lg w-full h-full object-contain
"
class=
"
max-w-full max-h-full object-contain rounded-lg transition-transform duration-300 group-hover:scale-110
"
/>
/>
</div>
</div>
<div
<div
class=
"p-3.5 border-t border-gray-100"
>
class=
"text-sm text-gray-700 mb-3 font-medium text-center line-clamp-2 min-h-[40px]"
<div
>
class=
"text-13px text-gray-800 font-medium line-clamp-2 min-h-[36px] leading-snug"
{{
item
.
name
}}
>
</div>
{{
item
.
name
}}
<div
class=
"bg-blue-600 text-white text-xs px-4 py-1.5 rounded font-medium"
>
</div>
{{
item
.
price
}}
积分
<div
class=
"mt-2.5 flex items-center justify-between"
>
<div
class=
"flex items-baseline gap-0.5"
>
<span
class=
"text-xs text-orange-400 font-medium"
>
¥
</span>
<span
class=
"text-xl font-bold text-orange-500"
>
{{
item
.
price
}}
</span>
<span
class=
"text-11px text-gray-400 ml-0.5"
>
积分
</span>
</div>
<span
class=
"text-11px text-gray-300"
>
库存
{{
item
.
stock
}}
</span>
</div>
</div>
</div>
<div
class=
"absolute inset-x-0 bottom-0 h-0.75 bg-gradient-to-r from-indigo-400 to-purple-400 scale-x-0 group-hover:scale-x-100 transition-transform duration-300 origin-left"
></div>
</div>
</div>
</div>
</div>
...
@@ -91,30 +101,40 @@
...
@@ -91,30 +101,40 @@
</div>
</div>
<
template
v-if=
"realGoodsList.length"
>
<
template
v-if=
"realGoodsList.length"
>
<div
class=
"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4"
>
<div
class=
"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4
xl:grid-cols-5
gap-4"
>
<div
<div
v-for=
"item in realGoodsList"
v-for=
"item in realGoodsList"
:key=
"item.id"
:key=
"item.id"
class=
"g
roup bg-white rounded-lg p-4 flex flex-col items-center shadow-md transition-all duration-200 cursor-pointer border border-gray-200 hover:border-blue
-300"
class=
"g
oods-card group relative bg-white rounded-xl overflow-hidden cursor-pointer border border-gray-200/80 shadow-sm hover:shadow-lg hover:-translate-y-1 transition-all duration
-300"
@
click=
"onExchangeGoods(item)"
@
click=
"onExchangeGoods(item)"
>
>
<div
<div
class=
"
w-20 h-20 mb-3 flex items-center justify-center bg-blue-50/50 rounded-lg p-2
"
class=
"
aspect-square bg-gradient-to-br from-gray-50 to-gray-100/80 overflow-hidden p-5 flex items-center justify-center
"
>
>
<img
<img
:src=
"item.imageUrl"
:src=
"item.imageUrl"
alt=
""
alt=
""
class=
"
rounded-lg w-full h-full object-contain
"
class=
"
max-w-full max-h-full object-contain rounded-lg transition-transform duration-300 group-hover:scale-110
"
/>
/>
</div>
</div>
<div
<div
class=
"p-3.5 border-t border-gray-100"
>
class=
"text-sm text-gray-700 mb-3 font-medium text-center line-clamp-2 min-h-[40px]"
<div
>
class=
"text-13px text-gray-800 font-medium line-clamp-2 min-h-[36px] leading-snug"
{{
item
.
name
}}
>
</div>
{{
item
.
name
}}
<div
class=
"bg-blue-600 text-white text-xs px-4 py-1.5 rounded font-medium"
>
</div>
{{
item
.
price
}}
积分
<div
class=
"mt-2.5 flex items-center justify-between"
>
<div
class=
"flex items-baseline gap-0.5"
>
<span
class=
"text-xs text-orange-400 font-medium"
>
¥
</span>
<span
class=
"text-xl font-bold text-orange-500"
>
{{
item
.
price
}}
</span>
<span
class=
"text-11px text-gray-400 ml-0.5"
>
积分
</span>
</div>
<span
class=
"text-11px text-gray-300"
>
库存
{{
item
.
stock
}}
</span>
</div>
</div>
</div>
<div
class=
"absolute inset-x-0 bottom-0 h-0.75 bg-gradient-to-r from-indigo-400 to-purple-400 scale-x-0 group-hover:scale-x-100 transition-transform duration-300 origin-left"
></div>
</div>
</div>
</div>
</div>
...
@@ -287,17 +307,14 @@ const onExchangeGoods = async (item: BackendShopItemDto) => {
...
@@ -287,17 +307,14 @@ const onExchangeGoods = async (item: BackendShopItemDto) => {
await
ElMessageBox
({
await
ElMessageBox
({
title
:
'YA币兑换'
,
title
:
'YA币兑换'
,
customStyle
:
{
customClass
:
'exchange-dialog'
,
width
:
'1000px'
,
},
message
:
()
=>
(
message
:
()
=>
(
// @ts-ignore
// @ts-ignore
<
ExchangeContent
item
=
{
item
}
v
-
model
=
{
form
.
value
}
><
/ExchangeContent
>
<
ExchangeContent
item
=
{
item
}
v
-
model
=
{
form
.
value
}
><
/ExchangeContent
>
),
),
confirmButtonText
:
'确认兑换'
,
confirmButtonText
:
'确认兑换'
,
cancelButtonText
:
'
取消
'
,
cancelButtonText
:
'
再想想
'
,
showCancelButton
:
true
,
showCancelButton
:
true
,
center
:
true
,
beforeClose
:
async
(
action
,
instance
,
done
)
=>
{
beforeClose
:
async
(
action
,
instance
,
done
)
=>
{
if
(
action
===
'cancel'
)
return
done
()
if
(
action
===
'cancel'
)
return
done
()
if
(
yabiData
.
value
.
currentValue
<
item
.
price
*
form
.
value
.
num
)
if
(
yabiData
.
value
.
currentValue
<
item
.
price
*
form
.
value
.
num
)
...
@@ -320,3 +337,44 @@ const onExchangeGoods = async (item: BackendShopItemDto) => {
...
@@ -320,3 +337,44 @@ const onExchangeGoods = async (item: BackendShopItemDto) => {
})
})
}
}
</
script
>
</
script
>
<
style
>
.exchange-dialog
{
border-radius
:
16px
!important
;
width
:
320px
!important
;
overflow
:
hidden
;
}
.exchange-dialog
.el-message-box__header
{
padding
:
20px
24px
0
;
}
.exchange-dialog
.el-message-box__title
{
font-size
:
16px
;
font-weight
:
600
;
}
.exchange-dialog
.el-message-box__content
{
padding
:
8px
24px
;
}
.exchange-dialog
.el-message-box__btns
{
padding
:
8px
24px
20px
;
}
.exchange-dialog
.el-message-box__btns
.el-button--primary
{
background
:
linear-gradient
(
to
right
,
#6366f1
,
#8b5cf6
);
border
:
none
;
border-radius
:
8px
;
padding
:
8px
28px
;
}
.exchange-dialog
.el-message-box__btns
.el-button--primary
:hover
{
opacity
:
0.9
;
}
.exchange-dialog
.el-message-box__btns
.el-button
:not
(
.el-button--primary
)
{
border-radius
:
8px
;
padding
:
8px
28px
;
}
</
style
>
src/views/userPage/index.vue
View file @
76422e6d
...
@@ -12,6 +12,9 @@
...
@@ -12,6 +12,9 @@
@
click=
"handleClearCache"
@
click=
"handleClearCache"
>
清除缓存
</el-button
>
清除缓存
</el-button
>
>
<el-button
type=
"info"
plain
size=
"small"
@
click=
"showOnlineTime = !showOnlineTime"
>
展示/隐藏在线时长
</el-button
>
<el-button
<el-button
v-if=
"officialAccountList.length"
v-if=
"officialAccountList.length"
type=
"info"
type=
"info"
...
@@ -153,7 +156,6 @@
...
@@ -153,7 +156,6 @@
</
template
>
</
template
>
<
script
lang=
"tsx"
setup
>
<
script
lang=
"tsx"
setup
>
import
{
useUserStore
}
from
'@/stores/user'
import
{
storeToRefs
}
from
'pinia'
import
{
storeToRefs
}
from
'pinia'
import
EditUserInfo
from
'./components/editUserInfo.vue'
import
EditUserInfo
from
'./components/editUserInfo.vue'
import
{
generateLoginKey
,
hasOfficialAccount
}
from
'@/api'
import
{
generateLoginKey
,
hasOfficialAccount
}
from
'@/api'
...
@@ -162,6 +164,9 @@ import { wxLogin } from '@/utils/wxUtil'
...
@@ -162,6 +164,9 @@ import { wxLogin } from '@/utils/wxUtil'
import
type
{
RouteLocationNormalizedLoadedGeneric
}
from
'vue-router'
import
type
{
RouteLocationNormalizedLoadedGeneric
}
from
'vue-router'
import
type
{
TabPaneName
}
from
'element-plus'
import
type
{
TabPaneName
}
from
'element-plus'
import
{
IS_REAL_KEY
}
from
'@/constants/symbolKey'
import
{
IS_REAL_KEY
}
from
'@/constants/symbolKey'
import
{
useOnlineTimeStore
,
useUserStore
}
from
'@/stores'
const
{
showOnlineTime
}
=
storeToRefs
(
useOnlineTimeStore
())
const
router
=
useRouter
()
const
router
=
useRouter
()
const
route
=
useRoute
()
const
route
=
useRoute
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment