Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
corporate-culture-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
王立鹏
corporate-culture-qd
Commits
d66ac723
Commit
d66ac723
authored
Aug 31, 2026
by
王立鹏
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'feature/23684-【YAYA文化岛】改动汇总' into 'master'
Feature/23684 【yaya文化岛】改动汇总 See merge request
!35
parents
a24b3b2b
e0f5e0ae
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
422 additions
and
135 deletions
+422
-135
index.html
index.html
+1
-1
index.ts
src/api/article/index.ts
+25
-0
types.ts
src/api/article/types.ts
+18
-0
index.ts
src/api/backend/activity/index.ts
+3
-2
types.ts
src/api/backend/activity/types.ts
+12
-2
types.ts
src/api/practice/types.ts
+1
-0
lucky-wheel-happy-adventure.mp3
src/assets/audio/lucky-wheel-happy-adventure.mp3
+0
-0
webicon.png
src/assets/img/webicon.png
+0
-0
index.vue
src/components/common/ArticleContent/index.vue
+69
-6
LuckyWheel.vue
...ents/common/LuckyWheelContainer/components/LuckyWheel.vue
+42
-9
index.vue
src/components/common/LuckyWheelContainer/index.vue
+32
-26
index.vue
src/components/common/PublishBox/index.vue
+22
-1
exchangeGoodsRecordDilaog.vue
src/views/auction/components/exchangeGoodsRecordDilaog.vue
+2
-2
exchangeYabiRecordDilaog.vue
src/views/auction/components/exchangeYabiRecordDilaog.vue
+1
-1
index.vue
src/views/auction/index.vue
+8
-1
index.vue
src/views/backend/contentsMenu/videoManage/index.vue
+21
-1
index.vue
src/views/backend/index.vue
+13
-13
index.vue
src/views/backend/settingsMenu/auctionManage/index.vue
+79
-16
lotteryConfigDialog.vue
...enu/dailyLotteryManage/components/lotteryConfigDialog.vue
+24
-5
index.vue
src/views/backend/settingsMenu/goodsManage/index.vue
+4
-4
index.vue
src/views/columnSearchList/index.vue
+1
-1
exchangeContent.tsx
src/views/pointsStore/components/exchangeContent.tsx
+16
-3
exchangeGoodsRecordDilaog.vue
...iews/pointsStore/components/exchangeGoodsRecordDilaog.vue
+2
-2
exchangeYabiRecordDilaog.vue
...views/pointsStore/components/exchangeYabiRecordDilaog.vue
+1
-1
index.vue
src/views/pointsStore/index.vue
+23
-36
index.vue
src/views/publishLongArticle/index.vue
+1
-1
index.vue
src/views/videoSearchList/index.vue
+1
-1
No files found.
index.html
View file @
d66ac723
...
...
@@ -2,7 +2,7 @@
<html
lang=
""
>
<head>
<meta
charset=
"UTF-8"
/>
<link
rel=
"icon"
href=
"/webicon.png"
/>
<link
rel=
"icon"
href=
"/
src/assets/img/
webicon.png"
/>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
/>
<title>
企业文化平台
</title>
</head>
...
...
src/api/article/index.ts
View file @
d66ac723
...
...
@@ -19,6 +19,9 @@ import type {
SearchMoreVideoItemDto
,
SecondCommentItemDto
,
UpdateArticleRecommendAndSortDto
,
RelatedColumnItemDto
,
RelatedColumnParams
,
UpdateArticleShowLatestDto
,
}
from
'./types'
import
type
{
BackendServicePageResult
,
PageSearchParams
}
from
'@/utils/request/types'
import
{
SpecificVideoRewardEnum
,
BooleanFlag
}
from
'@/constants'
...
...
@@ -396,3 +399,25 @@ export const getAtUserList = (
data
,
})
}
/**
* 根据标签获取专栏相关推荐
*/
export
const
getRelatedColumnList
=
(
data
:
RelatedColumnParams
)
=>
{
return
service
.
request
<
RelatedColumnItemDto
[]
>
({
url
:
'/api/cultureArticle/relatedByTag'
,
method
:
'POST'
,
data
,
})
}
/**
* 修改视频是否在首页最新列表展示
*/
export
const
updateArticleShowLatest
=
(
data
:
UpdateArticleShowLatestDto
)
=>
{
return
service
.
request
<
boolean
>
({
url
:
'/api/cultureArticle/updateShowLatest'
,
method
:
'POST'
,
data
,
})
}
src/api/article/types.ts
View file @
d66ac723
...
...
@@ -125,6 +125,7 @@ export interface AddOrUpdateVideoDto {
mainTagId
:
string
|
number
tagList
:
{
tagId
:
number
;
sort
:
number
}[]
|
number
[]
relateColumnId
?:
number
isShowLatest
?:
BooleanFlag
}
/**
...
...
@@ -212,6 +213,7 @@ export interface ArticleItemDto {
recommendSort
:
number
isOfficialAccount
:
BooleanFlag
deptId
:
string
isShowLatest
?:
BooleanFlag
}
/**
...
...
@@ -413,6 +415,7 @@ export interface SearchMoreColumnItemDto {
type
:
ArticleTypeEnum
.
COLUMN
videoDuration
:
string
viewCount
:
number
publishTime
:
number
}
/**
...
...
@@ -502,3 +505,18 @@ export interface AtUserInfoDto {
userId
:
number
version
:
number
}
export
interface
RelatedColumnParams
{
articleId
:
number
tagId
:
number
}
export
interface
RelatedColumnItemDto
{
id
:
number
title
:
string
}
export
interface
UpdateArticleShowLatestDto
{
articleId
:
number
isShowLatest
:
BooleanFlag
}
src/api/backend/activity/index.ts
View file @
d66ac723
...
...
@@ -2,6 +2,7 @@ import service from '@/utils/request/index'
import
type
{
BackendAuctionListSearchParams
,
BackendAuctionListItemDto
,
BackendDeleteAuctionDto
,
BackendAddOrUpdateAuctionItemDto
,
BackendAuctionRecordItemDto
,
BackendLotteryPrizeListSearchParams
,
...
...
@@ -44,11 +45,11 @@ export const addOrUpdateAuctionItem = (data: BackendAddOrUpdateAuctionItemDto) =
/**
* 删除竞拍物品数据
*/
export
const
deleteAuction
=
(
idList
:
number
[]
)
=>
{
export
const
deleteAuction
=
(
data
:
BackendDeleteAuctionDto
)
=>
{
return
service
.
request
({
url
:
'api/cultureAuctionItems/deleteAuction'
,
method
:
'POST'
,
data
:
{
idList
}
,
data
,
})
}
...
...
src/api/backend/activity/types.ts
View file @
d66ac723
...
...
@@ -36,8 +36,14 @@ export interface BackendAuctionListItemDto extends PageSearchParams {
remainingTime
:
string
}
export
interface
BackendDeleteAuctionDto
{
idList
:
number
[]
confirmDelete
:
boolean
}
export
interface
BackendAddOrUpdateAuctionItemDto
{
id
?:
number
status
?:
AuctionStatusEnum
name
:
string
quantity
:
number
specification
:
string
...
...
@@ -83,8 +89,10 @@ export interface BackendAddOrUpdateLotteryConfigDto {
startDate
:
string
endDate
:
string
autoCloseWeekend
:
BooleanFlag
registrationStartHour
:
string
registrationEndHour
:
string
registrationStartHour
:
number
registrationStartMinute
:
number
registrationEndHour
:
number
registrationEndMinute
:
number
registrationFee
:
number
}
...
...
@@ -98,8 +106,10 @@ export type BackendLotteryConfigDto = {
prizesImg
:
string
prizesName
:
string
registrationEndHour
:
number
registrationEndMinute
:
number
registrationFee
:
number
registrationStartHour
:
number
registrationStartMinute
:
number
startDate
:
number
status
:
BooleanFlag
updatedAt
:
number
...
...
src/api/practice/types.ts
View file @
d66ac723
...
...
@@ -15,6 +15,7 @@ export interface AddOrUpdatePracticeDto {
tagList
:
{
tagId
:
number
;
sort
:
number
}[]
sendType
:
SendTypeEnum
sendTime
:
string
deptId
?:
string
type
?:
ArticleTypeEnum
}
...
...
src/assets/audio/lucky-wheel-happy-adventure.mp3
0 → 100644
View file @
d66ac723
File added
public
/webicon.png
→
src/assets/img
/webicon.png
View file @
d66ac723
File moved
src/components/common/ArticleContent/index.vue
View file @
d66ac723
...
...
@@ -232,13 +232,48 @@
</div>
<!-- 标签 -->
<div
class=
"flex flex-wrap gap-2 mt-6"
>
<
span
v-for=
"
item
in articleDetail?.tagNameList"
<
el-tooltip
v-for=
"
(item, index)
in articleDetail?.tagNameList"
:key=
"item"
class=
"px-3 py-1 text-sm bg-gradient-to-r from-cyan-100 to-blue-100 text-cyan-600 rounded-full hover:shadow-md transition-all cursor-pointer"
:content=
"canLoadRelatedColumns ? '点击查看相关推荐专栏' : ''"
:disabled=
"!canLoadRelatedColumns"
placement=
"top"
:show-after=
"200"
>
#{{ item }}
</span>
<button
type=
"button"
:disabled=
"!canLoadRelatedColumns"
:class=
"[
'px-3 py-1 text-sm bg-gradient-to-r from-cyan-100 to-blue-100 text-cyan-600 rounded-full transition-all',
canLoadRelatedColumns ? 'cursor-pointer hover:shadow-md' : 'cursor-default',
activeKeyword === item ? 'ring-2 ring-cyan-400' : '',
]"
@
click=
"handleTagClick(item, articleDetail.tagIdList[index]!)"
>
#{{ item }}
</button>
</el-tooltip>
</div>
<div
v-if=
"canLoadRelatedColumns && activeKeyword"
v-loading=
"relatedColumnLoading"
class=
"mt-4 min-h-24 border-t border-gray-100 pt-4"
>
<h2
class=
"mb-3 text-sm font-semibold text-gray-700"
>
相关推荐专栏
</h2>
<ul
v-if=
"relatedColumnList.length"
class=
"space-y-2"
>
<li
v-for=
"(item, index) in relatedColumnList"
:key=
"item.id"
>
<button
type=
"button"
class=
"flex w-full items-center gap-2 text-left text-sm text-gray-600 hover:text-blue-600 cursor-pointer"
@
click=
"router.push(`/articleDetail/${item.id}`)"
>
<span
class=
"flex-shrink-0 text-gray-400"
>
{{ index + 1 }}.
</span>
<span
class=
"truncate"
>
{{ item.title }}
</span>
</button>
</li>
</ul>
<p
v-else-if=
"!relatedColumnLoading"
class=
"text-sm text-gray-400"
>
暂无相关推荐
</p>
</div>
</div>
</template>
...
...
@@ -258,7 +293,7 @@
<
script
setup
lang=
"ts"
>
import
dayjs
from
'dayjs'
import
type
{
Article
ItemDto
}
from
'@/api'
import
{
getRelatedColumnList
,
type
ArticleItemDto
,
type
RelatedColumn
ItemDto
}
from
'@/api'
import
{
articleTypeListOptions
,
ArticleTypeEnum
,
VideoPositionEnum
}
from
'@/constants'
import
ActionMore
from
'@/components/common/ActionMore/index.vue'
import
SendMessageDialog
from
'@/components/common/SendMessageDialog/index.vue'
...
...
@@ -290,6 +325,34 @@ const isReal = computed(() => {
const
loading
=
computed
(()
=>
!
articleDetail
.
title
)
// 只有专栏才能点击标签 获取相关推送
const
canLoadRelatedColumns
=
computed
(
()
=>
articleDetail
.
type
===
ArticleTypeEnum
.
COLUMN
&&
!
isAudit
,
)
// 点击标签后只展示当前关键词下的相关推荐专栏,列表由后端按优先级排好后再截取前三条。
const
activeKeyword
=
ref
(
''
)
const
relatedColumnLoading
=
ref
(
false
)
const
relatedColumnList
=
ref
<
RelatedColumnItemDto
[]
>
([])
const
handleTagClick
=
async
(
keyword
:
string
,
tagId
:
number
)
=>
{
if
(
!
canLoadRelatedColumns
.
value
)
return
activeKeyword
.
value
=
keyword
relatedColumnList
.
value
=
[]
relatedColumnLoading
.
value
=
true
try
{
const
{
data
}
=
await
getRelatedColumnList
({
articleId
:
articleDetail
.
id
,
tagId
,
})
relatedColumnList
.
value
=
data
.
slice
(
0
,
3
)
}
catch
{
relatedColumnList
.
value
=
[]
}
finally
{
relatedColumnLoading
.
value
=
false
}
}
// 是否是作者
const
isAuthor
=
computed
(()
=>
{
return
articleDetail
.
createUserId
===
userInfo
.
value
.
userId
...
...
src/components/common/LuckyWheelContainer/components/LuckyWheel.vue
View file @
d66ac723
...
...
@@ -30,6 +30,7 @@
<
script
lang=
"ts"
setup
>
import
{
LuckyWheel
}
from
'@lucky-canvas/vue'
import
ringTexture
from
'@/assets/img/lucky-wheel-outer-ring.svg'
import
spinMusic
from
'@/assets/audio/lucky-wheel-happy-adventure.mp3'
import
type
{
WheelPrizeItemDto
,
LuckWheelResultDto
,
WheelConfigDto
}
from
'@/api'
import
{
participateLuckyWheel
,
getWheelPrizeList
}
from
'@/api'
...
...
@@ -56,8 +57,8 @@ const myLucky = ref<InstanceType<typeof LuckyWheel>>()
const
defaultConfig
=
{
offsetDegree
:
0
,
speed
:
20
,
accelerationTime
:
25
00
,
decelerationTime
:
25
00
,
accelerationTime
:
10
00
,
decelerationTime
:
10
00
,
}
const
defaultStyle
=
{
...
...
@@ -124,18 +125,42 @@ const buttons = [
const
isSpinning
=
ref
(
false
)
let
resultPrize
:
null
|
LuckWheelResultDto
=
null
let
spinAudio
:
HTMLAudioElement
|
null
=
null
const
startSpinMusic
=
()
=>
{
stopSpinMusic
()
spinAudio
||=
new
Audio
(
spinMusic
)
spinAudio
.
loop
=
true
spinAudio
.
volume
=
0.35
spinAudio
.
play
().
catch
(()
=>
{})
}
const
stopSpinMusic
=
()
=>
{
if
(
!
spinAudio
)
return
spinAudio
.
pause
()
spinAudio
.
currentTime
=
0
}
const
startCallback
=
async
()
=>
{
if
(
isSpinning
.
value
)
return
isSpinning
.
value
=
true
startSpinMusic
()
myLucky
.
value
?.
play
()
setTimeout
(
async
()
=>
{
const
{
data
}
=
await
participateLuckyWheel
()
const
idx
=
computedPrizes
.
value
.
findIndex
((
item
)
=>
item
.
id
===
data
.
prizeId
)
myLucky
.
value
?.
stop
(
idx
)
yabiStore
.
fetchYaBiData
()
resultPrize
=
data
},
1000
)
try
{
const
{
data
}
=
await
participateLuckyWheel
()
const
idx
=
computedPrizes
.
value
.
findIndex
((
item
)
=>
item
.
id
===
data
.
prizeId
)
myLucky
.
value
?.
stop
(
idx
)
yabiStore
.
fetchYaBiData
()
resultPrize
=
data
}
catch
(
error
)
{
console
.
error
(
error
)
stopSpinMusic
()
isSpinning
.
value
=
false
}
},
600
)
}
// 获取最新的奖品列表 对比 是否更新了
...
...
@@ -185,7 +210,7 @@ const endCallback = () => {
setTimeout(() => {
isSpinning.value = false
emit('handlePrizeResult', resultPrize as LuckWheelResultDto)
},
50
0)
},
28
0)
}
const initWheelPrizeList = async () => {
...
...
@@ -195,6 +220,14 @@ const initWheelPrizeList = async () => {
onMounted(() => {
initWheelPrizeList()
})
onBeforeUnmount(() => {
stopSpinMusic()
})
defineExpose({
stopSpinMusic,
})
</
script
>
<
style
scoped
>
...
...
src/components/common/LuckyWheelContainer/index.vue
View file @
d66ac723
<
template
>
<Comp
:wheelConfig=
"wheelConfig"
@
handle-prize-result=
"handlePrizeResult"
/>
<Comp
ref=
"luckyWheelRef"
:wheelConfig=
"wheelConfig"
@
handle-prize-result=
"handlePrizeResult"
/>
<Teleport
to=
"body"
>
<Transition
name=
"result"
>
<div
...
...
@@ -84,7 +84,7 @@
<p
class=
"blessing-caption-subtitle"
>
抽一支好运电子签,把今天过得亮一点
</p>
</div>
<el-button
class=
"mt-8"
type=
"primary"
@
click=
"
showResult = false
"
>
知道了
</el-button>
<el-button
class=
"mt-8"
type=
"primary"
@
click=
"
closeResult
"
>
知道了
</el-button>
</
template
>
<
template
v-else
>
...
...
@@ -92,7 +92,7 @@
<div
class=
"mt-6 text-white text-3xl font-bold"
>
恭喜获得
{{
currentPrize
?.
prizeName
}}
</div>
<el-button
class=
"mt-8"
type=
"primary"
@
click=
"
showResult = false
"
>
知道了
</el-button>
<el-button
class=
"mt-8"
type=
"primary"
@
click=
"
closeResult
"
>
知道了
</el-button>
</
template
>
</div>
</Transition>
...
...
@@ -112,6 +112,7 @@ const { wheelConfig } = defineProps<{
const
showResult
=
ref
(
false
)
const
currentPrize
=
ref
<
LuckWheelResultDto
|
null
>
(
null
)
const
luckyWheelRef
=
ref
<
InstanceType
<
typeof
Comp
>>
()
const
blessingWrapRef
=
ref
<
HTMLElement
|
null
>
(
null
)
const
blessingGlowRef
=
ref
<
HTMLElement
|
null
>
(
null
)
...
...
@@ -305,10 +306,10 @@ const playBlessingAnimation = () => {
})
blessingTimeline
.
to
(
scene
,
{
opacity
:
1
,
y
:
0
,
duration
:
0.
4
5
})
.
to
(
glow
,
{
opacity
:
0.95
,
scale
:
1
,
duration
:
0.
7
,
ease
:
'sine.out'
},
'<'
)
.
to
(
slot
,
{
opacity
:
1
,
scaleX
:
1
,
duration
:
0.
52
},
'-=0.3
'
)
.
to
(
fan
,
{
opacity
:
1
,
y
:
0
,
duration
:
0.4
},
'<'
)
.
to
(
scene
,
{
opacity
:
1
,
y
:
0
,
duration
:
0.
3
5
})
.
to
(
glow
,
{
opacity
:
0.95
,
scale
:
1
,
duration
:
0.
55
,
ease
:
'sine.out'
},
'<'
)
.
to
(
slot
,
{
opacity
:
1
,
scaleX
:
1
,
duration
:
0.
42
},
'-=0.26
'
)
.
to
(
fan
,
{
opacity
:
1
,
y
:
0
,
duration
:
0.
3
4
},
'<'
)
.
to
(
fanItems
,
{
...
...
@@ -316,10 +317,10 @@ const playBlessingAnimation = () => {
y
:
(
_index
,
target
)
=>
Number
(
target
.
getAttribute
(
'data-y'
)
||
0
),
rotate
:
(
_index
,
target
)
=>
Number
(
target
.
getAttribute
(
'data-angle'
)
||
0
),
scale
:
(
_index
,
target
)
=>
Number
(
target
.
getAttribute
(
'data-scale'
)
||
1
),
duration
:
0.
9
,
duration
:
0.
7
,
ease
:
'back.out(1.08)'
,
stagger
:
{
each
:
0.0
55
,
each
:
0.0
42
,
from
:
'center'
,
},
},
...
...
@@ -329,16 +330,16 @@ const playBlessingAnimation = () => {
fanItems
,
{
x
:
(
_index
,
target
)
=>
Number
(
target
.
getAttribute
(
'data-x'
)
||
0
)
*
0.1
,
duration
:
0.
32
,
duration
:
0.
26
,
ease
:
'power1.inOut'
,
stagger
:
{
each
:
0.0
2
,
each
:
0.0
16
,
from
:
'edges'
,
},
yoyo
:
true
,
repeat
:
1
,
},
'+=0.
26
'
,
'+=0.
18
'
,
)
.
to
(
blessingTagStageRef
.
value
,
...
...
@@ -346,10 +347,10 @@ const playBlessingAnimation = () => {
opacity
:
1
,
y
:
0
,
filter
:
'blur(0px)'
,
duration
:
0.
48
,
duration
:
0.
36
,
ease
:
'power2.out'
,
},
'+=0.0
2
'
,
'+=0.0
1
'
,
)
.
to
(
tag
,
...
...
@@ -358,7 +359,7 @@ const playBlessingAnimation = () => {
opacity
:
0.5
,
scale
:
0.97
,
filter
:
'blur(6px)'
,
duration
:
0.
42
,
duration
:
0.
34
,
ease
:
'power2.out'
,
},
'<'
,
...
...
@@ -370,10 +371,10 @@ const playBlessingAnimation = () => {
opacity
:
1
,
scale
:
1.01
,
filter
:
'blur(1px)'
,
duration
:
1.08
,
duration
:
0.82
,
ease
:
'power3.out'
,
},
'+=0.
1
'
,
'+=0.
08
'
,
)
.
to
(
tag
,
...
...
@@ -382,10 +383,10 @@ const playBlessingAnimation = () => {
rotation
:
-
1.4
,
scale
:
1.015
,
filter
:
'blur(0px)'
,
duration
:
0.
3
,
duration
:
0.
24
,
ease
:
'power2.out'
,
},
'-=0.1
8
'
,
'-=0.1
4
'
,
)
.
to
(
tag
,
...
...
@@ -394,19 +395,19 @@ const playBlessingAnimation = () => {
rotation
:
0.4
,
scale
:
1
,
filter
:
'blur(0px)'
,
duration
:
0.
32
,
duration
:
0.
26
,
ease
:
'back.out(1.5)'
,
},
'+=0.0
2
'
,
'+=0.0
1
'
,
)
.
to
(
tagTop
,
{
opacity
:
1
,
duration
:
0.
22
},
'<'
)
.
to
(
tagTop
,
{
opacity
:
1
,
duration
:
0.
18
},
'<'
)
.
to
(
chars
,
{
opacity
:
1
,
y
:
0
,
duration
:
0.
34
,
stagger
:
0.05
,
duration
:
0.
28
,
stagger
:
0.0
3
5
,
},
'-=0.08'
,
)
...
...
@@ -415,7 +416,7 @@ const playBlessingAnimation = () => {
{
opacity
:
1
,
y
:
0
,
duration
:
0.2
8
,
duration
:
0.2
2
,
},
'-=0.12'
,
)
...
...
@@ -424,7 +425,7 @@ const playBlessingAnimation = () => {
{
opacity
:
1
,
y
:
0
,
duration
:
0.
42
,
duration
:
0.
34
,
},
'-=0.02'
,
)
...
...
@@ -461,6 +462,11 @@ const handlePrizeResult = (prize: LuckWheelResultDto) => {
currentPrize
.
value
=
prize
showResult
.
value
=
true
}
const
closeResult
=
()
=>
{
showResult
.
value
=
false
luckyWheelRef
.
value
?.
stopSpinMusic
()
}
</
script
>
<
style
>
...
...
src/components/common/PublishBox/index.vue
View file @
d66ac723
...
...
@@ -62,6 +62,21 @@
:height=
"100"
/>
</div>
<div
v-if=
"userInfo.isOfficialAccount && type === ArticleTypeEnum.PRACTICE"
class=
"mb-3"
>
<el-select
v-model=
"form.deptId"
placeholder=
"请选择所属一级部门"
clearable
class=
"w-full"
>
<el-option
v-for=
"item in firstDepListOptions"
:key=
"item.id"
:value=
"item.id"
:label=
"item.name"
/>
</el-select>
</div>
<!-- 标签内容 -->
<div
class=
"mb-2"
>
<!-- 选择的标签内容 -->
...
...
@@ -148,7 +163,12 @@ import { useUserStore } from '@/stores'
import
{
storeToRefs
}
from
'pinia'
import
SelectTagsDialog
from
'./components/selectTagsDialog.vue'
import
{
useResetData
,
useUploadImg
}
from
'@/hooks'
import
{
ArticleTypeEnum
,
ReleaseStatusTypeEnum
,
SendTypeEnum
}
from
'@/constants'
import
{
ArticleTypeEnum
,
firstDepListOptions
,
ReleaseStatusTypeEnum
,
SendTypeEnum
,
}
from
'@/constants'
import
{
useTagsStore
}
from
'@/stores'
import
{
addOrUpdatePractice
,
addOrUpdateArticle
}
from
'@/api'
import
type
{
AddOrUpdatePracticeDto
}
from
'@/api'
...
...
@@ -238,6 +258,7 @@ const [form, , forReset] = useResetData({
tagList
:
[],
sendType
:
SendTypeEnum
.
IMMEDIATE
,
sendTime
:
''
,
deptId
:
''
,
})
const
{
imgList
,
handleFileChange
,
handleDeleteImg
,
uploadPercent
}
=
useUploadImg
(
...
...
src/views/auction/components/exchangeGoodsRecordDilaog.vue
View file @
d66ac723
...
...
@@ -13,7 +13,7 @@
<div
class=
"w-750px flex items-center gap-3"
>
<el-select
v-model=
"searchParams.itemType"
placeholder=
"选择商品类型"
clearable
>
<el-option
label=
"亚声实物"
:value=
"ShopGoodsTypeEnum.REAL_GOODS"
/>
<el-option
label=
"虚拟
装饰
"
:value=
"ShopGoodsTypeEnum.VIRTUAL_GOODS"
/>
<el-option
label=
"虚拟
商品
"
:value=
"ShopGoodsTypeEnum.VIRTUAL_GOODS"
/>
</el-select>
<el-date-picker
...
...
@@ -38,7 +38,7 @@
<el-table-column
prop=
"itemType"
label=
"商品类型"
width=
"100"
align=
"center"
>
<template
#
default=
"scope"
>
{{
scope
.
row
.
itemType
===
ShopGoodsTypeEnum
.
REAL_GOODS
?
'亚声实物'
:
'虚拟
装饰
'
}}
{{
scope
.
row
.
itemType
===
ShopGoodsTypeEnum
.
REAL_GOODS
?
'亚声实物'
:
'虚拟
商品
'
}}
</
template
>
</el-table-column>
...
...
src/views/auction/components/exchangeYabiRecordDilaog.vue
View file @
d66ac723
...
...
@@ -13,7 +13,7 @@
<div
class=
"w-750px flex items-center gap-3"
>
<!--
<el-select
v-model=
"searchParams.type"
placeholder=
"选择商品类型"
clearable
>
<el-option
label=
"亚声实物"
:value=
"ShopGoodsTypeEnum.REAL_GOODS"
/>
<el-option
label=
"虚拟
装饰
"
:value=
"ShopGoodsTypeEnum.VIRTUAL_GOODS"
/>
<el-option
label=
"虚拟
商品
"
:value=
"ShopGoodsTypeEnum.VIRTUAL_GOODS"
/>
</el-select>
-->
<el-date-picker
...
...
src/views/auction/index.vue
View file @
d66ac723
...
...
@@ -175,10 +175,17 @@ const onBid = async (item: AuctionItemDto) => {
}
else
{
if
(
val
.
value
>
yabiData
.
value
.
currentValue
)
return
push
.
error
(
'您的YA币余额不足'
)
if
(
val
.
value
<
data
.
minIncrement
+
(
data
.
currentPrice
||
data
.
startingPrice
))
// 如果还没有出价 只需要出价大于等于起拍价
if
(
data
.
currentPrice
===
0
)
{
if
(
val
.
value
<
data
.
startingPrice
)
return
push
.
error
(
`出价必须大于等于起拍价: 至少【
${
data
.
startingPrice
}
】YA币`
,
)
}
else
{
if
(
val
.
value
<
data
.
minIncrement
+
(
data
.
currentPrice
||
data
.
startingPrice
))
return
push
.
error
(
`出价必须大于等于前最高出价+最低加价幅度: 至少【
${
data
.
minIncrement
+
(
data
.
currentPrice
||
data
.
startingPrice
)}
】YA币`
,
)
}
instance
.
confirmButtonLoading
=
true
instance
.
confirmButtonText
=
'Loading...'
...
...
src/views/backend/contentsMenu/videoManage/index.vue
View file @
d66ac723
...
...
@@ -2,7 +2,7 @@
import
{
Search
,
Upload
}
from
'@element-plus/icons-vue'
import
{
usePageSearch
,
useResetData
}
from
'@/hooks'
import
{
addOrUpdateColumn
}
from
'@/api/backend'
import
{
getArticleList
,
updateArticleRecommendAndSort
}
from
'@/api'
import
{
getArticleList
,
updateArticleRecommendAndSort
,
updateArticleShowLatest
}
from
'@/api'
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
type
{
BackendColumnListItemDto
,
AddOrUpdateColumnDto
}
from
'@/api/backend'
import
dayjs
from
'dayjs'
...
...
@@ -51,6 +51,15 @@ const handleIsRecommendChange = async (val: BooleanFlag, row: ArticleItemDto) =>
refresh
()
}
const
handleIsShowLatestChange
=
async
(
val
:
BooleanFlag
,
row
:
ArticleItemDto
)
=>
{
await
updateArticleShowLatest
({
articleId
:
row
.
id
,
isShowLatest
:
val
,
})
push
.
success
(
'修改成功'
)
refresh
()
}
// 编辑排序
const
handleEditSort
=
async
(
row
:
ArticleItemDto
)
=>
{
const
value
=
await
prompt
({
...
...
@@ -155,6 +164,17 @@ const handleSelectionChange = (selection: BackendColumnListItemDto[]) => {
</
template
>
</el-table-column>
<el-table-column
prop=
"isShowLatest"
label=
"是否在最新出现"
min-width=
"160"
>
<
template
#
default=
"{ row }"
>
<el-switch
:model-value=
"row.isShowLatest ?? BooleanFlag.YES"
:active-value=
"BooleanFlag.YES"
:inactive-value=
"BooleanFlag.NO"
@
change=
"(val) => handleIsShowLatestChange(val as BooleanFlag, row)"
/>
</
template
>
</el-table-column>
<el-table-column
prop=
"status"
label=
"是否推荐"
min-width=
"200"
>
<
template
#
header
>
<div
class=
"flex items-center gap-2"
>
...
...
src/views/backend/index.vue
View file @
d66ac723
<
script
lang=
"tsx"
>
import
{
KeepAlive
,
Transition
}
from
'vue'
import
type
{
Component
as
VueComponent
}
from
'vue'
import
webIconUrl
from
'@/assets/img/webicon.png'
export
default
defineComponent
(()
=>
{
interface
MenuItem
{
path
:
string
...
...
@@ -23,7 +24,6 @@ export default defineComponent(() => {
// { path: '/backend/videoManage', title: '视频管理' },
{
path
:
'/backend/caseManage'
,
title
:
'YAYA案例库管理'
},
// { path: '/backend/goodsManage', title: '积分商城——商品配置' },
{
path
:
'/backend/goodsDistribution'
,
title
:
'商品分发'
},
// 内容管理
{
path
:
'/backend/contentsMenu'
,
...
...
@@ -35,7 +35,16 @@ export default defineComponent(() => {
{
path
:
'/backend/contentsMenu/questionManage'
,
title
:
'问吧管理'
},
],
},
// 栏目管理
{
path
:
'/backend/columnsMenu'
,
title
:
'栏目管理'
,
children
:
[
{
path
:
'/backend/columnsMenu/columnManage'
,
title
:
'专栏——栏目管理'
},
{
path
:
'/backend/columnsMenu/interviewManage'
,
title
:
'专访——栏目管理'
},
{
path
:
'/backend/columnsMenu/videoManage'
,
title
:
'视频——栏目管理'
},
],
},
// 配置管理
{
path
:
'/backend/settingsMenu'
,
...
...
@@ -47,16 +56,7 @@ export default defineComponent(() => {
{
path
:
'/backend/settingsMenu/luckyWheelManage'
,
title
:
'转盘抽奖配置'
},
],
},
// 栏目管理
{
path
:
'/backend/columnsMenu'
,
title
:
'栏目管理'
,
children
:
[
{
path
:
'/backend/columnsMenu/columnManage'
,
title
:
'专栏——栏目管理'
},
{
path
:
'/backend/columnsMenu/interviewManage'
,
title
:
'专访——栏目管理'
},
{
path
:
'/backend/columnsMenu/videoManage'
,
title
:
'视频——栏目管理'
},
],
},
{
path
:
'/backend/goodsDistribution'
,
title
:
'商品分发'
},
]
const
activeMenu
=
computed
(()
=>
route
.
path
)
...
...
@@ -111,7 +111,7 @@ export default defineComponent(() => {
<
div
class
=
"backend-layout"
>
<
aside
class
=
"backend-sidebar"
>
<
div
class
=
"sidebar-header"
>
<
img
src
=
"/webicon.png"
alt
=
"SOUNDASIA"
class
=
"logo"
/>
<
img
src
=
{
webIconUrl
}
alt
=
"SOUNDASIA"
class
=
"logo"
/>
<
span
class
=
"header-title"
>
企业文化后台管理
<
/span
>
<
/div
>
...
...
src/views/backend/settingsMenu/auctionManage/index.vue
View file @
d66ac723
...
...
@@ -88,7 +88,7 @@
{{
// 未展示的时候不展示竞拍状态
row
.
isDisplay
===
0
?
''
?
'
未展示在前台时不展示竞拍状态
'
:
auctionStatusListOptions
.
find
((
item
)
=>
item
.
value
===
row
.
status
)?.
label
}}
</
template
>
...
...
@@ -195,6 +195,17 @@
inactive-text=
"否"
/>
</el-form-item>
<el-form-item
v-if=
"form.id"
label=
"竞拍状态"
prop=
"status"
>
<el-select
v-model=
"form.status"
placeholder=
"请选择竞拍状态"
class=
"w-60%!"
>
<el-option
v-for=
"item in editAuctionStatusOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
:disabled=
"item.disabled"
/>
</el-select>
</el-form-item>
</el-form>
</el-scrollbar>
<
template
#
footer
>
...
...
@@ -221,7 +232,7 @@ import {
}
from
'@/api/backend'
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
type
{
BackendAuctionListItemDto
,
BackendAddOrUpdateAuctionItemDto
}
from
'@/api/backend'
import
{
auctionStatusListOptions
}
from
'@/constants'
import
{
AuctionStatusEnum
,
auctionStatusListOptions
}
from
'@/constants'
import
UploadFile
from
'@/components/common/UploadFile/index.vue'
import
AuctionRecordDialog
from
'./components/auctionRecordDialog.vue'
import
dayjs
from
'dayjs'
...
...
@@ -253,19 +264,45 @@ const [form, resetForm] = useResetData<BackendAddOrUpdateAuctionItemDto>({
isDisplay
:
0
,
startTime
:
''
,
endTime
:
''
,
status
:
undefined
,
})
// 可编辑的 竞拍状态 只可以选择 「竞拍成功 / 已流拍」
const
editAuctionStatusOptions
=
computed
(()
=>
{
const
options
=
auctionStatusListOptions
.
filter
((
item
)
=>
[
AuctionStatusEnum
.
AUCTION_SUCCESS
,
AuctionStatusEnum
.
AUCTION_FAILED
].
includes
(
item
.
value
),
)
.
map
((
item
)
=>
({
...
item
,
disabled
:
false
,
}))
const
hasCurrentStatus
=
options
.
some
((
item
)
=>
item
.
value
===
form
.
value
.
status
)
if
(
form
.
value
.
status
!==
undefined
&&
!
hasCurrentStatus
)
{
const
currentStatus
=
auctionStatusListOptions
.
find
((
item
)
=>
item
.
value
===
form
.
value
.
status
)
options
.
unshift
({
label
:
currentStatus
?.
label
||
`未知状态(
${
form
.
value
.
status
}
)`
,
value
:
form
.
value
.
status
,
disabled
:
true
,
})
}
return
options
})
// 表单验证规则
const
formRules
:
FormRules
=
{
name
:
[{
required
:
true
,
message
:
'请输入名称'
,
trigger
:
'blur'
}],
description
:
[{
required
:
true
,
message
:
'请输入介绍内容'
,
trigger
:
'blur'
}],
quantity
:
[{
required
:
true
,
message
:
'请输入数量'
,
trigger
:
'blur'
}],
specification
:
[{
required
:
true
,
message
:
'请输入规格'
,
trigger
:
'blur'
}],
//
specification: [{ required: true, message: '请输入规格', trigger: 'blur' }],
startingPrice
:
[{
required
:
true
,
message
:
'请输入起拍价'
,
trigger
:
'blur'
}],
minIncrement
:
[{
required
:
true
,
message
:
'请输入最低加价幅度'
,
trigger
:
'blur'
}],
bidLimit
:
[{
required
:
true
,
message
:
'请输入竞拍次数上限'
,
trigger
:
'blur'
}],
startTime
:
[{
required
:
true
,
message
:
'请选择竞拍时间'
,
trigger
:
'change'
}],
isDisplay
:
[{
required
:
true
,
message
:
'请选择是否展示在前台'
,
trigger
:
'blur'
}],
imageUrl
:
[{
required
:
true
,
message
:
'请上传图片'
,
trigger
:
'change'
}],
status
:
[{
required
:
true
,
message
:
'请选择竞拍状态'
,
trigger
:
'change'
}],
}
const
dateRange
=
computed
({
get
()
{
...
...
@@ -304,21 +341,18 @@ const handleEdit = (row: BackendAddOrUpdateAuctionItemDto) => {
// 删除
const
handleDelete
=
async
(
row
:
BackendAuctionListItemDto
)
=>
{
const
confirmDelete
=
row
.
currentPrice
>
0
await
confirm
({
title
:
'提示'
,
message
:
`确定要删除竞拍物品"
${
row
.
name
}
"吗?`
,
message
:
confirmDelete
?
'该竞拍已有人出价,是否确定删除?删除后无法恢复,并会同步删除竞拍者的记录'
:
`确定要删除竞拍物品"
${
row
.
name
}
"吗?`
,
type
:
'danger'
,
})
try
{
await
deleteAuction
([
row
.
id
])
refresh
()
push
.
success
(
'删除成功'
)
refresh
()
}
catch
(
error
)
{
if
(
error
!==
'cancel'
)
{
push
.
error
(
'删除失败'
)
}
}
await
deleteAuction
({
idList
:
[
row
.
id
],
confirmDelete
})
refresh
()
push
.
success
(
'删除成功'
)
}
// 提交表单
...
...
@@ -384,13 +418,42 @@ const handleBatchShow = async () => {
}
const
handleBatchDelete
=
async
()
=>
{
const
bidRows
=
selectedRows
.
value
.
filter
((
item
)
=>
item
.
currentPrice
>
0
)
const
unbidRows
=
selectedRows
.
value
.
filter
((
item
)
=>
item
.
currentPrice
===
0
)
const
formatNames
=
(
rows
:
BackendAuctionListItemDto
[])
=>
rows
.
map
((
item
)
=>
`【
${
item
.
name
}
】`
).
join
(
''
)
let
message
=
`确定要删除竞拍物品
${
formatNames
(
unbidRows
)}
吗?`
if
(
bidRows
.
length
&&
unbidRows
.
length
)
{
message
=
`其中
${
formatNames
(
bidRows
)}
这些竞拍已有人出价,是否确定删除?删除后无法恢复,并会同步删除竞拍者的记录,其余
${
formatNames
(
unbidRows
)}
未出价会正常删除,确定删除吗?`
}
else
if
(
bidRows
.
length
)
{
message
=
`
${
formatNames
(
bidRows
)}
这些竞拍已有人出价,是否确定删除?删除后无法恢复,并会同步删除竞拍者的记录,确定删除吗?`
}
await
confirm
({
title
:
'提示'
,
message
:
'确定要删除这些竞拍物品吗?'
,
message
,
type
:
'danger'
,
})
await
deleteAuction
(
selectedRows
.
value
.
map
((
item
)
=>
item
.
id
))
if
(
unbidRows
.
length
&&
bidRows
.
length
)
{
await
Promise
.
all
([
deleteAuction
({
idList
:
unbidRows
.
map
((
item
)
=>
item
.
id
),
confirmDelete
:
false
,
}),
deleteAuction
({
idList
:
bidRows
.
map
((
item
)
=>
item
.
id
),
confirmDelete
:
true
,
}),
])
}
else
{
const
rows
=
bidRows
.
length
?
bidRows
:
unbidRows
await
deleteAuction
({
idList
:
rows
.
map
((
item
)
=>
item
.
id
),
confirmDelete
:
bidRows
.
length
>
0
,
})
}
refresh
()
push
.
success
(
'删除成功'
)
}
...
...
src/views/backend/settingsMenu/dailyLotteryManage/components/lotteryConfigDialog.vue
View file @
d66ac723
...
...
@@ -38,8 +38,8 @@
start-placeholder=
"开始时间"
end-placeholder=
"结束时间"
is-range
format=
"HH:
00
"
value-format=
"H"
format=
"HH:
mm
"
value-format=
"H
H:mm
"
/>
</el-form-item>
<!-- 报名费用 -->
...
...
@@ -93,6 +93,18 @@ const visible = ref(false)
const
formRef
=
ref
<
FormInstance
>
()
const
loading
=
ref
(
false
)
const
formatRegistrationTime
=
(
hour
:
number
,
minute
=
0
)
=>
`
${
String
(
hour
).
padStart
(
2
,
'0'
)}
:
${
String
(
minute
).
padStart
(
2
,
'0'
)}
`
const
parseRegistrationTime
=
(
time
:
string
)
=>
{
const
[
hour
=
0
,
minute
=
0
]
=
time
.
split
(
':'
).
map
(
Number
)
return
{
hour
,
minute
,
}
}
const
open
=
async
()
=>
{
const
{
data
}
=
await
getLotteryConfigDetail
()
if
(
!
data
)
{
...
...
@@ -102,7 +114,10 @@ const open = async () => {
id
:
data
.
id
,
openRangeTime
:
[
String
(
data
.
startDate
),
String
(
data
.
endDate
)],
autoCloseWeekend
:
data
.
autoCloseWeekend
,
registrationRangeTime
:
[
String
(
data
.
registrationStartHour
),
String
(
data
.
registrationEndHour
)],
registrationRangeTime
:
[
formatRegistrationTime
(
data
.
registrationStartHour
,
data
.
registrationStartMinute
),
formatRegistrationTime
(
data
.
registrationEndHour
,
data
.
registrationEndMinute
),
],
registrationFee
:
data
.
registrationFee
,
}
}
...
...
@@ -111,12 +126,16 @@ const open = async () => {
const
handleSubmit
=
async
()
=>
{
await
formRef
.
value
?.
validate
()
const
registrationStartTime
=
parseRegistrationTime
(
form
.
value
.
registrationRangeTime
[
0
]
!
)
const
registrationEndTime
=
parseRegistrationTime
(
form
.
value
.
registrationRangeTime
[
1
]
!
)
const
data
=
{
startDate
:
form
.
value
.
openRangeTime
[
0
]
!
,
endDate
:
formatSeconds
(
form
.
value
.
openRangeTime
[
1
]
!
),
autoCloseWeekend
:
form
.
value
.
autoCloseWeekend
,
registrationStartHour
:
form
.
value
.
registrationRangeTime
[
0
]
!
,
registrationEndHour
:
form
.
value
.
registrationRangeTime
[
1
]
!
,
registrationStartHour
:
registrationStartTime
.
hour
,
registrationStartMinute
:
registrationStartTime
.
minute
,
registrationEndHour
:
registrationEndTime
.
hour
,
registrationEndMinute
:
registrationEndTime
.
minute
,
registrationFee
:
form
.
value
.
registrationFee
,
}
loading
.
value
=
true
...
...
src/views/backend/settingsMenu/goodsManage/index.vue
View file @
d66ac723
...
...
@@ -20,7 +20,7 @@
clearable
>
<el-option
v-for=
"item in
r
egionListOptions"
v-for=
"item in
goodsR
egionListOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
...
...
@@ -77,7 +77,7 @@
<el-table-column
prop=
"price"
label=
"兑换所需YA币"
min-width=
"200"
>
</el-table-column>
<el-table-column
prop=
"
show
Name"
label=
"创建人"
min-width=
"200"
/>
<el-table-column
prop=
"
createUser
Name"
label=
"创建人"
min-width=
"200"
/>
<el-table-column
prop=
"createTime"
label=
"创建时间"
min-width=
"200"
>
<
template
#
default=
"{ row }"
>
...
...
@@ -147,7 +147,7 @@
<el-form-item
label=
"上架地区"
prop=
"region"
>
<el-select
v-model=
"form.region"
placeholder=
"请选择上架地区"
>
<el-option
v-for=
"item in
r
egionListOptions"
v-for=
"item in
goodsR
egionListOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
...
...
@@ -197,7 +197,7 @@ import type { BackendShopItemDto } from '@/api/backend'
import
{
push
}
from
'notivue'
import
{
useMessageBox
}
from
'@/hooks'
const
{
confirm
}
=
useMessageBox
()
const
goodsRegionListOptions
=
[...
regionListOptions
,
{
label
:
'四地通用'
,
value
:
'四地通用'
}]
const
{
loading
,
list
,
total
,
reset
,
goToPage
,
changePageSize
,
refresh
,
searchParams
,
search
}
=
usePageSearch
(
getShopItemList
)
...
...
src/views/columnSearchList/index.vue
View file @
d66ac723
...
...
@@ -100,7 +100,7 @@
<!-- 底部信息 -->
<div
class=
"flex items-center gap-4 text-13px text-gray-500"
>
<span>
{{ item.showName }}
</span>
<span>
{{ dayjs(item.
create
Time * 1000).format('YYYY-MM-DD HH:mm:ss') }}
</span>
<span>
{{ dayjs(item.
publish
Time * 1000).format('YYYY-MM-DD HH:mm:ss') }}
</span>
<div
class=
"flex items-center gap-1"
>
<el-icon
class=
"text-sm"
>
<IEpView
/>
...
...
src/views/pointsStore/components/exchangeContent.tsx
View file @
d66ac723
...
...
@@ -5,6 +5,11 @@ import { ShopGoodsTypeEnum, regionListOptions } from '@/constants'
import
type
{
BackendShopItemDto
,
ExchangeGoodsParams
}
from
'@/api'
import
type
{
SetupContext
}
from
'vue'
const
UNIVERSAL_REGION
=
'四地通用'
const
universalRegionOptions
=
regionListOptions
.
filter
((
item
)
=>
[
'深圳'
,
'合肥'
,
'武汉'
,
'长沙'
].
includes
(
item
.
value
),
)
type
ExchangeContentProps
=
{
item
:
BackendShopItemDto
modelValue
:
ExchangeGoodsParams
...
...
@@ -17,7 +22,14 @@ export default function ExchangeContent(
{
item
,
modelValue
}:
ExchangeContentProps
,
context
:
SetupContext
<
ExchangeContentEvents
>
,
)
{
const
totalPrice
=
computed
(()
=>
item
.
price
*
(
modelValue
.
num
||
1
))
const
totalPrice
=
item
.
price
*
(
modelValue
.
num
||
1
)
const
deliveryOfficeOptions
=
item
.
region
===
UNIVERSAL_REGION
?
universalRegionOptions
:
(()
=>
{
const
currentRegion
=
regionListOptions
.
find
((
region
)
=>
region
.
value
===
item
.
region
)
return
currentRegion
?
[
currentRegion
]
:
[{
label
:
item
.
region
,
value
:
item
.
region
}]
})()
return
(
<
div
class=
"py-4"
>
...
...
@@ -58,8 +70,9 @@ export default function ExchangeContent(
}
placeholder=
"请选择办公点"
class=
"w-full"
disabled=
{
item
.
region
!==
UNIVERSAL_REGION
}
>
{
regionList
Options
.
map
((
office
)
=>
(
{
deliveryOffice
Options
.
map
((
office
)
=>
(
<
el
-
option
key=
{
office
.
value
}
label=
{
office
.
label
}
value=
{
office
.
value
}
/>
))
}
</
el
-
select
>
...
...
@@ -94,7 +107,7 @@ export default function ExchangeContent(
</
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-2xl font-bold text-orange-500"
>
{
totalPrice
}
</
span
>
<
span
class=
"text-xs text-gray-400 ml-1"
>
积分
</
span
>
</
div
>
</
div
>
...
...
src/views/pointsStore/components/exchangeGoodsRecordDilaog.vue
View file @
d66ac723
...
...
@@ -13,7 +13,7 @@
<div
class=
"w-750px flex items-center gap-3"
>
<el-select
v-model=
"searchParams.itemType"
placeholder=
"选择商品类型"
clearable
>
<el-option
label=
"亚声实物"
:value=
"ShopGoodsTypeEnum.REAL_GOODS"
/>
<el-option
label=
"虚拟
装饰
"
:value=
"ShopGoodsTypeEnum.VIRTUAL_GOODS"
/>
<el-option
label=
"虚拟
商品
"
:value=
"ShopGoodsTypeEnum.VIRTUAL_GOODS"
/>
</el-select>
<el-date-picker
...
...
@@ -38,7 +38,7 @@
<el-table-column
prop=
"itemType"
label=
"商品类型"
width=
"100"
align=
"center"
>
<template
#
default=
"scope"
>
{{
scope
.
row
.
itemType
===
ShopGoodsTypeEnum
.
REAL_GOODS
?
'亚声实物'
:
'虚拟
装饰
'
}}
{{
scope
.
row
.
itemType
===
ShopGoodsTypeEnum
.
REAL_GOODS
?
'亚声实物'
:
'虚拟
商品
'
}}
</
template
>
</el-table-column>
...
...
src/views/pointsStore/components/exchangeYabiRecordDilaog.vue
View file @
d66ac723
...
...
@@ -13,7 +13,7 @@
<div
class=
"w-750px flex items-center gap-3"
>
<!--
<el-select
v-model=
"searchParams.type"
placeholder=
"选择商品类型"
clearable
>
<el-option
label=
"亚声实物"
:value=
"ShopGoodsTypeEnum.REAL_GOODS"
/>
<el-option
label=
"虚拟
装饰
"
:value=
"ShopGoodsTypeEnum.VIRTUAL_GOODS"
/>
<el-option
label=
"虚拟
商品
"
:value=
"ShopGoodsTypeEnum.VIRTUAL_GOODS"
/>
</el-select>
-->
<el-date-picker
...
...
src/views/pointsStore/index.vue
View file @
d66ac723
...
...
@@ -4,13 +4,13 @@
<BackButton
/>
<!-- 左侧:商品列表区域 -->
<div
class=
"flex-3/4 min-w-0"
>
<!-- 虚拟
装饰
区域 -->
<!-- 虚拟
商品
区域 -->
<div
class=
"bg-white/90 rounded-lg p-6 shadow-lg mb-3 border border-white/60"
>
<div
class=
"flex items-center gap-3 mb-6"
>
<div
class=
"w-1.5 h-7 bg-gradient-to-b from-[#8b5cf6] to-[#6366f1] rounded-full shadow-sm"
></div>
<h2
class=
"text-xl font-bold text-gray-800"
>
虚拟
装饰
</h2>
<h2
class=
"text-xl font-bold text-gray-800"
>
虚拟
商品
</h2>
</div>
<template
v-if=
"virtualGoodsList.length"
>
...
...
@@ -78,27 +78,6 @@
<h2
class=
"text-xl font-bold text-gray-800"
>
亚声实物
</h2>
</div>
<!-- 地区筛选 -->
<div
class=
"flex gap-3 text-sm mb-6 items-center flex-wrap"
>
<span
class=
"text-gray-600 font-medium"
>
地区:
</span>
<button
v-for=
"item in tabs"
:key=
"item.value"
class=
"cursor-pointer px-3 py-1.5 text-sm transition-all relative"
@
click=
"onChangeRegion(item.value)"
:class=
"{
'text-indigo-600 font-medium': realGoodsSearchParams.region === item.value,
'text-gray-600 hover:text-gray-900': realGoodsSearchParams.region !== item.value,
}"
>
{{ item.label }}
<span
v-if=
"realGoodsSearchParams.region === item.value"
class=
"absolute bottom-0 left-0 right-0 h-0.5 bg-gradient-to-b from-[#8b5cf6] to-[#6366f1]"
></span>
</button>
</div>
<
template
v-if=
"realGoodsList.length"
>
<div
class=
"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4"
>
<div
...
...
@@ -211,7 +190,7 @@
<!-- 统计信息(可选) -->
<div
class=
"mt-6 pt-6 border-t border-gray-100 space-y-3"
>
<div
class=
"flex justify-between items-center text-sm"
>
<span
class=
"text-gray-500"
>
虚拟
装饰
</span>
<span
class=
"text-gray-500"
>
虚拟
商品
</span>
<span
class=
"font-medium text-gray-700"
>
{{ virtualGoodsTotal }} 件
</span>
</div>
<div
class=
"flex justify-between items-center text-sm"
>
...
...
@@ -231,7 +210,7 @@
<
script
setup
lang=
"tsx"
>
import
{
exchangeGoods
,
getShopItemList
}
from
'@/api'
import
{
usePageSearch
}
from
'@/hooks'
import
{
regionListOptions
,
ShopGoodsTypeEnum
}
from
'@/constants'
import
{
ShopGoodsTypeEnum
}
from
'@/constants'
import
type
{
ExchangeGoodsParams
,
BackendShopItemDto
}
from
'@/api'
import
ExchangeContent
from
'./components/exchangeContent.tsx'
import
ExchangeGoodsRecordDialog
from
'./components/exchangeGoodsRecordDilaog.vue'
...
...
@@ -242,9 +221,7 @@ import BackButton from '@/components/common/BackButton/index.vue'
import
{
push
}
from
'notivue'
const
yabiStore
=
useYaBiStore
()
const
{
yabiData
}
=
storeToRefs
(
yabiStore
)
const
activeTab
=
ref
(
'深圳'
)
const
tabs
=
ref
(
regionListOptions
)
const
UNIVERSAL_REGION
=
'四地通用'
const
exchangeGoodsRecordDialogRef
=
useTemplateRef
<
InstanceType
<
typeof
ExchangeGoodsRecordDialog
>>
(
'exchangeGoodsRecordDialogRef'
,
...
...
@@ -276,15 +253,9 @@ const {
}
=
usePageSearch
(
getShopItemList
,
{
defaultParams
:
{
itemType
:
ShopGoodsTypeEnum
.
REAL_GOODS
,
region
:
activeTab
.
value
,
},
})
const
onChangeRegion
=
(
region
:
string
)
=>
{
realGoodsSearchParams
.
value
.
region
=
region
realGoodsGoToPage
(
1
)
}
const
onOpenExchangeYabiRecordDialog
=
()
=>
{
exchangeYabiRecordDialogRef
.
value
?.
open
()
}
...
...
@@ -296,12 +267,16 @@ const onOpenExchangeGoodsRecordDialog = () => {
// 兑换商品
const
onExchangeGoods
=
async
(
item
:
BackendShopItemDto
)
=>
{
if
(
item
.
stock
===
0
)
return
push
.
warning
(
'库存为0,不可兑换'
)
const
form
=
ref
<
ExchangeGoodsParams
>
({
itemId
:
item
.
id
,
num
:
1
,
})
if
(
item
.
itemType
===
ShopGoodsTypeEnum
.
REAL_GOODS
)
{
form
.
value
.
deliveryInfo
=
'广州'
const
isRealGoods
=
item
.
itemType
===
ShopGoodsTypeEnum
.
REAL_GOODS
const
isUniversalRegion
=
item
.
region
===
UNIVERSAL_REGION
if
(
isRealGoods
&&
!
isUniversalRegion
)
{
form
.
value
.
deliveryInfo
=
item
.
region
}
await
ElMessageBox
({
...
...
@@ -320,6 +295,18 @@ const onExchangeGoods = async (item: BackendShopItemDto) => {
return
push
.
error
(
`您的YA币不足,兑换所需
${
item
.
price
*
form
.
value
.
num
}
YA币,当前YA币
${
yabiData
.
value
.
currentValue
}
`
,
)
if
(
isRealGoods
&&
!
form
.
value
.
deliveryInfo
)
return
push
.
warning
(
'请选择配送办公点'
)
if
(
isRealGoods
&&
isUniversalRegion
)
{
try
{
await
ElMessageBox
.
confirm
(
'请确认配送办公点准确性,准确无误可继续提交'
,
'提示'
,
{
confirmButtonText
:
'继续提交'
,
cancelButtonText
:
'返回修改'
,
type
:
'warning'
,
})
}
catch
{
return
}
}
try
{
instance
.
confirmButtonLoading
=
true
await
exchangeGoods
(
form
.
value
)
...
...
src/views/publishLongArticle/index.vue
View file @
d66ac723
...
...
@@ -37,7 +37,7 @@
</
template
>
<
template
v-else
>
<!-- 回显回来可能会有bug 所以需要key 重新渲染一下-->
<WangEditor
:key
v-model=
"form.content"
/>
<WangEditor
:key
v-model=
"form.content"
/>
</
template
>
</el-form-item>
</div>
...
...
src/views/videoSearchList/index.vue
View file @
d66ac723
...
...
@@ -104,7 +104,7 @@
<!-- 底部信息 -->
<div
class=
"flex items-center gap-4 text-13px text-gray-500"
>
<span>
{{ item.showName }}
</span>
<span>
{{ dayjs(item.
create
Time * 1000).format('YYYY-MM-DD HH:mm:ss') }}
</span>
<span>
{{ dayjs(item.
publish
Time * 1000).format('YYYY-MM-DD HH:mm:ss') }}
</span>
<div
class=
"flex items-center gap-1"
>
<el-icon
class=
"text-sm"
>
<IEpView
/>
...
...
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