Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
C
company_app
概览
概览
详情
活动
周期分析
版本库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
毛细亚
company_app
Commits
a96af5d6
提交
a96af5d6
authored
11月 24, 2025
作者:
毛细亚
浏览文件
操作
浏览文件
下载
差异文件
合并分支 'release' 到 'master'
上线掌游 10.4 版本 查看合并请求
!34
上级
a3ab1107
5593e9ce
显示空白字符变更
内嵌
并排
正在显示
12 个修改的文件
包含
1171 行增加
和
92 行删除
+1171
-92
game.js
src/api/game.js
+43
-0
applyGift.vue
src/views/components/giftRecord/applyGift.vue
+45
-18
confirmLayer.vue
src/views/components/giftRecord/confirmLayer.vue
+6
-3
emailGift.vue
src/views/components/giftRecord/emailGift.vue
+33
-1
oneDay.vue
src/views/components/giftRecord/giftDetails/oneDay.vue
+86
-5
roleRecharge.vue
src/views/components/giftRecord/giftDetails/roleRecharge.vue
+3
-2
roleTimeRecharge.vue
...ws/components/giftRecord/giftDetails/roleTimeRecharge.vue
+79
-4
SendEmailDialog.vue
src/views/components/taskList/SendEmailDialog.vue
+212
-0
taskDetails.vue
src/views/components/taskList/taskDetails.vue
+124
-51
uesrTask.vue
src/views/components/taskList/uesrTask.vue
+35
-2
benefitusageRecord.vue
...views/userInfo/components/gameInfo/benefitusageRecord.vue
+309
-0
vipLevel.vue
src/views/userInfo/components/gameInfo/vipLevel.vue
+196
-6
没有找到文件。
src/api/game.js
浏览文件 @
a96af5d6
...
...
@@ -1424,3 +1424,46 @@ export function getClonePackageLink(data) {
})
})
}
// 使用权益
export
function
useBenefit
(
data
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
cross_systemRequest
({
system
:
'zhangyou'
,
api
:
'/api/marketing_role_grade/useRight'
,
params
:
data
}).
then
((
res
)
=>
{
resolve
(
res
)
}).
catch
((
error
)
=>
{
reject
(
error
)
})
})
}
// 使用权益记录
export
function
useRightList
(
data
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
cross_systemRequest
({
system
:
'zhangyou'
,
api
:
'/api/marketing_role_grade/useRightList'
,
params
:
data
}).
then
((
res
)
=>
{
resolve
(
res
)
}).
catch
((
error
)
=>
{
reject
(
error
)
})
})
}
// 发送邮件
export
function
sendEmail
(
data
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
cross_systemRequest
({
system
:
'zhangyou'
,
api
:
'/api/operator_task/sendEmail'
,
params
:
data
}).
then
((
res
)
=>
{
resolve
(
res
)
}).
catch
((
error
)
=>
{
reject
(
error
)
})
})
}
src/views/components/giftRecord/applyGift.vue
浏览文件 @
a96af5d6
...
...
@@ -8,22 +8,22 @@
>
<div>
<el-form
ref=
"ruleForm"
:model=
"ruleForm"
label-width=
"100px"
class=
"content"
>
<el-form-item
label=
"选择角色"
>
<el-form-item
label=
"选择角色
:
"
>
<el-select
v-model=
"ruleForm.role_id"
placeholder=
"请选择角色"
style=
"width:90%;margin-bottom:10px;"
@
change=
"selectRole"
>
<el-option
v-for=
"(item,index) in roleList"
:key=
"i
ndex+1
"
:key=
"i
tem.value
"
:label=
"item.label"
:value=
"item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"活动类型"
>
<el-form-item
label=
"活动类型
:
"
>
<el-select
v-model=
"ruleForm.gift_type"
placeholder=
"请选择"
style=
"width:90%;margin-bottom:10px;"
@
change=
"giftTypeResult"
>
<el-option
v-for=
"(item,index) in giftTypeList"
:key=
"i
ndex+1
"
:key=
"i
tem.value
"
:label=
"item.label"
:value=
"item.value"
>
...
...
@@ -31,11 +31,11 @@
</el-select>
</el-form-item>
<!-- 活动类型为角色累充的时候 活动可以多选其他的都为单选 -->
<el-form-item
label=
"选择活动"
prop=
"rule_id"
>
<el-form-item
label=
"选择活动
:
"
prop=
"rule_id"
>
<el-select
v-model=
"ruleForm.rule_id"
:disabled=
"activeList.length==0"
placeholder=
"请选择"
style=
"width:90%;margin-bottom:10px;"
:multiple=
"ruleForm.gift_type==1 || ruleForm.gift_type == 4 || ruleForm.gift_type== 5 "
clearable
@
change=
"activeListResult"
>
<el-option
v-for=
"(item,index) in activeList"
:key=
"i
ndex+1
"
:key=
"i
tem.id
"
:label=
"item.title_name"
:value=
"item.id"
>
...
...
@@ -56,16 +56,16 @@
</el-form>
<!-- 申请礼包 -->
<!-- 角色累充 -->
<roleRecharge
v-if=
"showGiftDetails && (ruleForm.gift_type==1 || ruleForm.gift_type==4 || ruleForm.gift_type==5) && roleActiveInfo.length>0"
:show
.
sync=
"showGiftDetails"
:request-loading=
"requestLoading"
:active-info=
"roleActiveInfo"
:gift-info=
"giftDetailsInfo"
title=
"礼包详情"
/>
<roleRecharge
v-if=
"showGiftDetails && (ruleForm.gift_type==1 || ruleForm.gift_type==4 || ruleForm.gift_type==5) && roleActiveInfo.length>0"
:show
.
sync=
"showGiftDetails"
:request-loading=
"requestLoading"
:active-info=
"roleActiveInfo"
:
task_id=
"task_id"
:
gift-info=
"giftDetailsInfo"
title=
"礼包详情"
/>
<!-- 时间段累充 和 单日累充 积分关的情况 -->
<roleTimeRecharge
v-if=
"showGiftDetails && (ruleForm.gift_type==2 ||
(ruleForm.gift_type==3 && activeInfo.exchange_score_status==2 ) ) && activeInfo.id "
:change-date=
"changeDate"
:request-loading=
"requestLoading
"
:show
.
sync=
"showGiftDetails"
:active-info=
"activeInfo"
:gift-info=
"giftDetailsInfo"
title=
"礼包详情"
@
changeDateResult=
"changeDateResult"
@
giftDetailsInfo=
"requestDetailsInfo"
/>
<!-- 单日累充 积分开的情况 -->
<oneDayCharge
v-if=
"showGiftDetails && ruleForm.gift_type==3 && activeInfo.exchange_score_status==1 && activeInfo.id"
:show
.
sync=
"showGiftDetails"
:request-loading=
"requestLoading"
:active-info=
"activeInfo"
:change-date=
"changeDate"
:gift-info=
"giftDetailsInfo"
title=
"礼包详情"
@
changeDateResult=
"changeDateResult"
@
giftDetailsInfo=
"requestDetailsInfo"
/>
<roleTimeRecharge
v-if=
"showGiftDetails && (ruleForm.gift_type==2 ||
ruleForm.gift_type == 7 || (ruleForm.gift_type==3 && activeInfo.exchange_score_status==2 ) ) && activeInfo.id "
:change-date=
"changeDate"
:request-loading=
"requestLoading"
:task_id=
"task_id
"
:show
.
sync=
"showGiftDetails"
:active-info=
"activeInfo"
:gift-info=
"giftDetailsInfo"
title=
"礼包详情"
@
changeDateResult=
"changeDateResult"
@
giftDetailsInfo=
"requestDetailsInfo"
/>
<!-- 单日累充 积分开的情况
显示 svip 权益 并且可以选择 svip权益
-->
<oneDayCharge
v-if=
"showGiftDetails && (ruleForm.gift_type==3 || ruleForm.gift_type == 7) && activeInfo.exchange_score_status==1 && activeInfo.id"
:show
.
sync=
"showGiftDetails"
:task_id=
"task_id"
:request-loading=
"requestLoading"
:active-info=
"activeInfo"
:change-date=
"changeDate"
:gift-info=
"giftDetailsInfo"
title=
"礼包详情"
@
changeDateResult=
"changeDateResult"
@
giftDetailsSVIPInfo=
"giftDetailsSVIPInfo"
@
giftDetailsInfo=
"requestDetailsInfo"
/>
</div>
</el-drawer>
</
template
>
<
script
type=
"text/javascript"
>
import
{
roleList
,
activeList
,
giftBagApply
,
giftTypeList
,
giftDetailsData
}
from
'@/api/game'
import
{
getRoleHoLo
,
activeList
,
giftBagApply
,
giftTypeList
,
giftDetailsData
}
from
'@/api/game'
import
{
mapState
,
mapMutations
,
mapActions
}
from
'vuex'
// import giftDetails from './giftDetails.vue'
import
roleRecharge
from
'./giftDetails/roleRecharge.vue'
...
...
@@ -79,8 +79,8 @@
oneDayCharge
,
// 单日累充
roleTimeRecharge
// 角色时间段累充
},
// type 3:image 4:video
props
:
[
'show'
,
'width'
,
'title'
],
// type 3:image 4:video
task_id // 账号任务点击礼包申请过来传递的任务id member_id // 我的任务 任务详情 点击 礼包申请的时候 需要用到任务详情的 member_id,这时候需要传递过来
props
:
[
'show'
,
'width'
,
'title'
,
'task_id'
,
'member_id'
],
data
()
{
return
{
roleList
:
[],
...
...
@@ -124,6 +124,15 @@
this
.
requestRoleList
()
this
.
giftTypeListData
()
},
beforeDestroy
()
{
// 清理组件销毁时的状态,防止内存泄漏
this
.
roleList
=
[]
this
.
activeList
=
[]
this
.
giftTypeList
=
[]
this
.
roleActiveInfo
=
[]
this
.
activeInfo
=
{}
this
.
giftDetailsInfo
=
{}
},
methods
:
{
requestActiveList
()
{
if
(
this
.
ruleForm
.
role_id
!==
''
&&
this
.
ruleForm
.
gift_type
!==
''
)
{
...
...
@@ -156,15 +165,18 @@
})
},
requestRoleList
()
{
if
(
this
.
accountSelect
==
''
)
{
if
(
this
.
accountSelect
==
''
&&
!
this
.
member_id
)
{
this
.
$message
.
warning
(
'暂无关联的账号,请先去关联账号!'
)
return
false
}
const
data
=
{
api_search_name
:
''
,
member_id
:
this
.
accountSelect
member_id
:
this
.
member_id
||
this
.
accountSelect
,
// 先取任务详情的member_id,没有的话取账号的member_id
search_type
:
'list'
,
page_size
:
100
,
page
:
1
}
roleList
(
data
).
then
(
res
=>
{
getRoleHoLo
(
data
).
then
(
res
=>
{
if
(
res
.
status_code
==
1
)
{
if
(
res
.
data
.
data
.
length
>
0
)
{
const
list
=
res
.
data
.
data
.
sort
((
a
,
b
)
=>
{
return
Number
(
b
.
recharge_total
)
-
Number
(
a
.
recharge_total
)
})
...
...
@@ -197,7 +209,7 @@
this
.
activeList
=
[]
const
gift_type
=
this
.
giftTypeList
.
find
(
item
=>
item
.
value
==
data
)
console
.
log
(
gift_type
,
'gift_type'
)
this
.
gift_type_text
=
gift_type
.
label
this
.
gift_type_text
=
gift_type
.
label
||
''
this
.
requestActiveList
()
this
.
activeInfo
=
{}
this
.
giftInfo
=
{}
...
...
@@ -246,7 +258,7 @@
this
.
showGiftDetails
=
true
}
else
{
this
.
ruleForm
.
recharge_date
=
''
if
(
this
.
ruleForm
.
gift_type
==
2
)
{
if
(
this
.
ruleForm
.
gift_type
==
2
||
this
.
ruleForm
.
gift_type
==
7
)
{
this
.
requestGiftDetails
()
this
.
showGiftDetails
=
true
}
...
...
@@ -274,6 +286,21 @@
this
.
$message
.
warning
(
'请选择充值日期'
)
}
},
// 积分开的情况 显示 svip 权益 并且可以选择 svip权益
giftDetailsSVIPInfo
(
params
){
console
.
log
(
params
,
'params'
)
const
data
=
{
role_id
:
this
.
ruleForm
.
role_id
,
rule_id
:
this
.
ruleForm
.
rule_id
.
toString
(),
recharge_date
:
params
.
recharge_date
||
''
,
right_type
:
params
.
right_type
||
''
,
select_type
:
params
.
select_type
||
''
}
giftDetailsData
(
data
).
then
(
res
=>
{
this
.
giftDetailsInfo
=
res
.
data
this
.
showGiftDetails
=
true
})
},
requestGiftDetails
(
value
)
{
const
data
=
{
role_id
:
this
.
ruleForm
.
role_id
,
...
...
src/views/components/giftRecord/confirmLayer.vue
浏览文件 @
a96af5d6
...
...
@@ -55,7 +55,7 @@
</div>
</div>
<!-- 活动列表 -->
<span
class=
"
dialog-footer
rowFlex"
>
<span
class=
"rowFlex"
>
<el-button
class=
"btn"
type=
"primary"
:loading=
"loading"
@
click=
"submit"
>
确 定
</el-button>
<el-button
class=
"btn"
@
click=
"close"
>
取 消
</el-button>
</span>
...
...
@@ -68,7 +68,7 @@
export
default
{
name
:
'confirmLayer'
,
// type 3:image 4:video
props
:
[
'show'
,
'width'
,
'title'
,
'activeInfo'
,
'remark'
],
props
:
[
'show'
,
'width'
,
'title'
,
'activeInfo'
,
'remark'
,
'task_id'
,
'svipObj'
],
data
()
{
return
{
loading
:
false
...
...
@@ -104,8 +104,11 @@
role_id
,
remark
:
this
.
remark
,
recharge_date
:
this
.
activeInfo
[
0
].
recharge_date
||
''
,
task_id
:
this
.
task_id
||
null
,
create_user
:
this
.
cser_name
,
rule
:
rule
rule
:
rule
,
right_type
:
this
.
svipObj
?.
right_type
||
''
,
select_type
:
this
.
svipObj
?.
select_type
||
''
}
giftBagApply
(
data
).
then
(
res
=>
{
this
.
loading
=
false
...
...
src/views/components/giftRecord/emailGift.vue
浏览文件 @
a96af5d6
...
...
@@ -28,6 +28,13 @@
</el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"svip权益"
>
<el-select
v-model
.
trim=
"form.right_type"
filterable
style=
"width:100%;"
placeholder=
"请选择svip权益"
@
change=
"searchInput"
>
<el-option
v-for=
"item in benefitOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"角色名称"
>
<el-input
v-model=
"form.role_name_or_cp_id"
placeholder=
"请输入角色名称"
style=
"width:100%;"
@
change=
"searchInput"
></el-input>
...
...
@@ -59,6 +66,7 @@
<
/div
>
<
el
-
collapse
-
transition
>
<
div
v
-
if
=
"item.showDetails"
>
<
p
class
=
"text hidden"
><
label
>
svip
权益
:
<
/label> {{ item.right_type_name || '-'
}}
</
p
>
<
p
v
-
if
=
"item.status == '待提交'"
class
=
"text"
><
label
>
状态:
<
/label> <span class="noSend">{{ item.statu
s
}}
<
/span> </
p
>
<
p
v
-
else
-
if
=
"item.status == '已提交'"
class
=
"text"
><
label
>
状态:
<
/label> <span class="sended">{{
...
...
@@ -165,8 +173,10 @@ export default {
role_name_or_cp_id
:
''
,
member_id
:
''
,
active_title
:
''
,
gift_type
:
''
gift_type
:
''
,
right_type
:
''
,
}
,
benefitOptions
:
[],
inputValue
:
''
,
pageInfo
:
{
page
:
0
,
...
...
@@ -198,6 +208,7 @@ export default {
mounted
()
{
this
.
requestGameList
()
this
.
requestGiftType
()
this
.
getBenefitOptions
()
}
,
methods
:
{
// 重新拉去数据
...
...
@@ -286,6 +297,27 @@ export default {
this
.
emailGiftList
=
[]
this
.
requestemailGiftList
()
}
,
async
getBenefitOptions
()
{
try
{
const
data
=
{
type
:
'svip_right'
,
}
const
res
=
await
selectSearch
(
data
)
if
(
res
.
status_code
===
1
&&
res
.
data
&&
res
.
data
.
data
&&
res
.
data
.
data
.
length
>
0
)
{
const
showList
=
[
'转生石福利'
,
'月核心玩家礼包'
,
'超R生日福利礼包'
,
'超R行会专属礼包'
]
this
.
benefitOptions
=
res
.
data
.
data
.
filter
((
item
,
index
)
=>
{
return
showList
.
includes
(
item
.
label
)
}
).
map
(
item
=>
({
...
item
,
value
:
item
.
value
||
item
.
id
// 确保每个选项都有value属性,优先使用value,不存在则使用id
}
));
console
.
log
(
this
.
benefitOptions
)
}
}
catch
(
error
)
{
console
.
error
(
'获取权益选项失败:'
,
error
)
}
}
,
requestemailGiftList
()
{
this
.
listLoading
=
true
if
(
this
.
accountSelect
==
''
)
{
...
...
src/views/components/giftRecord/giftDetails/oneDay.vue
浏览文件 @
a96af5d6
...
...
@@ -24,9 +24,23 @@
<div
class=
"activeValue"
>
{{
activeInfo
.
recharge_start_date
+
'至'
+
activeInfo
.
recharge_end_date
}}
</div>
</div>
<!-- 选择的时候重新请求活动详情接口 -->
<div
class=
"activeItem rowFlex"
>
<div
class=
"activeLabel"
>
充值日期
</div>
<div
style=
"display: flex; align-items: center;width: 100%;"
>
<el-select
v-model=
"select_type"
:clearable=
"false"
style=
"width: 120px"
@
change=
"onSelectTypeChange"
>
<el-option
label=
"充值日期"
:value=
"1"
></el-option>
<el-option
label=
"SVIP权益"
:value=
"2"
></el-option>
</el-select>
<template
v-if=
"select_type === 1"
>
<el-date-picker
v-model=
"recharge_date_time"
:default-value=
"activeInfo.recharge_date"
style=
"width: 210px"
type=
"date"
value-format=
"yyyy-MM-dd"
:picker-options=
"activeInfo.pickerOptions "
@
change=
"dateChange"
>
</el-date-picker>
</
template
>
<
template
v-else-if=
"select_type === 2"
>
<el-select
v-model=
"right_type"
:clearable=
"false"
style=
"width: 210px"
placeholder=
"请选择权益"
@
change=
"onRightTypeChange"
>
<el-option
v-for=
"item in benefitOptions"
:key=
"item.id || item.value"
:label=
"item.label"
:value=
"item.value || item.id"
></el-option>
</el-select>
</
template
>
</div>
</div>
<div
class=
"activeItem rowFlex"
>
<div
class=
"activeLabel"
>
申请角色
</div>
...
...
@@ -127,13 +141,13 @@
<el-button
class=
"btn"
size=
"small"
@
click=
"close"
>
取 消
</el-button>
</span>
<!-- 确认弹窗 -->
<confirmLayer
v-if=
"showConfirmLayer"
:remark=
"remark"
:
active-info=
"[activeInfo]"
:show
.
sync=
"showConfirmLayer"
title=
"请核对申请奖品信息"
@
close=
"close"
/>
<confirmLayer
v-if=
"showConfirmLayer"
:remark=
"remark"
:
task_id=
"task_id"
:active-info=
"[activeInfo]"
:show
.
sync=
"showConfirmLayer"
:svipObj=
"svipObj"
title=
"请核对申请奖品信息"
@
close=
"close"
/>
</div>
</el-drawer>
</template>
<
script
type=
"text/javascript"
>
import
{
giftBagApply
}
from
'@/api/game'
import
{
giftBagApply
,
selectSearch
}
from
'@/api/game'
import
{
mapState
,
mapMutations
,
mapActions
}
from
'vuex'
import
confirmLayer
from
'../confirmLayer'
export
default
{
...
...
@@ -142,7 +156,7 @@ export default {
components
:
{
confirmLayer
},
props
:
[
'show'
,
'width'
,
'title'
,
'info'
,
'body'
,
'giftInfo'
,
'activeInfo'
,
'changeDate'
,
'requestLoading'
],
props
:
[
'show'
,
'width'
,
'title'
,
'info'
,
'body'
,
'giftInfo'
,
'activeInfo'
,
'changeDate'
,
'requestLoading'
,
'task_id'
],
data
()
{
return
{
remark
:
''
,
...
...
@@ -155,7 +169,16 @@ export default {
num
:
''
,
allpoints
:
0
,
showContent
:
true
,
showConfirmLayer
:
false
benefitOptions
:[],
showConfirmLayer
:
false
,
svipObj
:
{
right_type
:
''
,
select_type
:
''
},
// 新增:1 充值日期 2 svip权益
select_type
:
1
,
// 权益类型选中的值
right_type
:
''
}
},
...
...
@@ -175,7 +198,18 @@ export default {
},
mounted
()
{
this
.
recharge_date_time
=
this
.
activeInfo
.
recharge_date
this
.
getBenefitOptions
()
},
computed
:
{
// 根据选择类型显示对应的内容
showDatePicker
()
{
return
this
.
select_type
===
1
},
showBenefitSelect
()
{
return
this
.
select_type
===
2
}
},
methods
:
{
close
()
{
this
.
$emit
(
'update:show'
,
false
)
...
...
@@ -187,6 +221,50 @@ export default {
this
.
$emit
(
'giftDetailsInfo'
,
value
)
}
},
async
getBenefitOptions
()
{
try
{
const
data
=
{
type
:
'svip_right'
,
}
const
res
=
await
selectSearch
(
data
)
if
(
res
.
status_code
===
1
&&
res
.
data
&&
res
.
data
.
data
&&
res
.
data
.
data
.
length
>
0
)
{
const
showList
=
[
'月核心玩家礼包'
,
'超R生日福利礼包'
]
this
.
benefitOptions
=
res
.
data
.
data
.
filter
((
item
,
index
)
=>
{
return
showList
.
includes
(
item
.
label
)
}).
map
(
item
=>
({
...
item
,
value
:
item
.
value
||
item
.
id
// 确保每个选项都有value属性,优先使用value,不存在则使用id
}));
console
.
log
(
this
.
benefitOptions
)
}
}
catch
(
error
)
{
console
.
error
(
'获取权益选项失败:'
,
error
)
}
},
// 选择类型改变时触发
onSelectTypeChange
()
{
// 重置选择的值
if
(
this
.
select_type
===
1
)
{
this
.
recharge_date_time
=
this
.
activeInfo
.
recharge_date
// 触发日期变化的接口
this
.
dateChange
(
this
.
recharge_date_time
)
}
else
{
this
.
right_type
=
''
}
},
// 权益类型改变时触发
onRightTypeChange
()
{
if
(
this
.
right_type
)
{
const
data
=
{
right_type
:
this
.
right_type
,
select_type
:
this
.
select_type
}
// 复用日期变化的接口
this
.
$emit
(
'giftDetailsSVIPInfo'
,
data
)
}
},
openPrizeItem
(
item
,
index
,
value
)
{
console
.
log
(
item
,
index
,
value
)
this
.
$set
(
this
.
giftInfo
.
rule
.
level_attribute
[
index
],
'showContent'
,
value
)
...
...
@@ -242,6 +320,8 @@ export default {
}
this
.
showConfirmLayer
=
true
this
.
activeInfo
.
type_details
=
this
.
giftInfo
this
.
svipObj
.
right_type
=
this
.
right_type
this
.
svipObj
.
select_type
=
this
.
select_type
}
}
}
...
...
@@ -360,6 +440,7 @@ export default {
left
:
50%
;
transform
:
translateX
(
-50%
);
bottom
:
100px
;
z-index
:
100
;
}
.consumption-point
{
font-size
:
14px
;
...
...
src/views/components/giftRecord/giftDetails/roleRecharge.vue
浏览文件 @
a96af5d6
...
...
@@ -57,7 +57,7 @@
<el-button
size=
"small"
class=
"btn"
@
click=
"close"
>
取 消
</el-button>
</span>
<!-- 确认弹窗 -->
<confirmLayer
:is-submit=
"isSubmit"
:remark=
"remark"
:active-info=
"activeInfo"
:show
.
sync=
"showConfirmLayer"
title=
"请核对申请奖品信息"
@
close=
"close"
/>
<confirmLayer
:is-submit=
"isSubmit"
:remark=
"remark"
:
task_id=
"task_id"
:
active-info=
"activeInfo"
:show
.
sync=
"showConfirmLayer"
title=
"请核对申请奖品信息"
@
close=
"close"
/>
</div>
</el-drawer>
</
template
>
...
...
@@ -72,7 +72,7 @@ export default {
components
:
{
confirmLayer
},
props
:
[
'show'
,
'width'
,
'title'
,
'info'
,
'body'
,
'giftInfo'
,
'activeInfo'
,
'requestLoading'
],
props
:
[
'show'
,
'width'
,
'title'
,
'info'
,
'body'
,
'giftInfo'
,
'activeInfo'
,
'requestLoading'
,
'task_id'
],
data
()
{
return
{
isSubmit
:
false
,
...
...
@@ -121,6 +121,7 @@ export default {
role_id
,
remark
:
this
.
remark
,
recharge_date
:
this
.
activeInfo
[
0
].
recharge_date
||
''
,
task_id
:
this
.
task_id
||
null
,
create_user
:
this
.
cser_name
,
rule
:
rule
}
...
...
src/views/components/giftRecord/giftDetails/roleTimeRecharge.vue
浏览文件 @
a96af5d6
...
...
@@ -64,8 +64,30 @@
class=
"activeValue"
>
{{
activeInfo
.
role_info
.
label
}}
</div>
</div>
<div
class=
"activeItem rowFlex"
>
<div
class=
"activeLabel"
>
SVIP权益
</div>
<div
v-if=
"giftInfo.rule?.right_type_name"
class=
"activeValue"
>
{{
giftInfo
.
rule
?.
right_type_name
||
'-'
}}
</div>
</div>
<div
class=
"rowFlex"
>
<div
class=
"activeItem rowFlex"
>
<div
class=
"activeLabel"
style=
"width: 70px"
>
可领取次数
</div>
<div
v-if=
"giftInfo.total_recharge"
class=
"activeValue"
>
{{
giftInfo
.
total_recharge
||
'-'
}}
</div>
</div>
<div
class=
"activeItem rowFlex"
>
<div
class=
"activeLabel"
style=
"width: 90px"
>
剩余领取次数
</div>
<div
v-if=
"giftInfo.real_score"
class=
"activeValue"
>
{{
giftInfo
.
real_score
||
'-'
}}
</div>
</div>
</div>
<!-- 积分关的情况 -->
<div
v-if=
"activeInfo.gift_type == 2"
class=
"activeItem rowFlex"
...
...
@@ -234,7 +256,7 @@
type=
"primary"
size=
"small"
:disabled=
"requestLoading"
@
click=
"submit"
@
click=
"submit
Btn
"
:loading=
"btnLoading"
>
确 定
</el-button>
<el-button
...
...
@@ -247,6 +269,7 @@
<confirmLayer
v-if=
"showConfirmLayer"
:remark=
"remark"
:task_id=
"task_id"
:active-info=
"[activeInfo]"
:show
.
sync=
"showConfirmLayer"
title=
"请核对申请奖品信息"
...
...
@@ -266,7 +289,7 @@ export default {
components
:
{
confirmLayer
},
props
:
[
'show'
,
'width'
,
'title'
,
'info'
,
'body'
,
'giftInfo'
,
'activeInfo'
,
'changeDate'
,
'requestLoading'
],
props
:
[
'show'
,
'width'
,
'title'
,
'info'
,
'body'
,
'giftInfo'
,
'activeInfo'
,
'changeDate'
,
'requestLoading'
,
'task_id'
],
data
()
{
return
{
remark
:
''
,
...
...
@@ -385,7 +408,59 @@ export default {
handleChange
()
{
},
async
submit
()
{
submitBtn
(){
// svip 权益礼包
if
(
this
.
activeInfo
.
gift_type
==
7
){
this
.
submitSvipGfit
()
}
else
{
this
.
submitGift
()
}
},
submitSvipGfit
(){
this
.
loading
=
true
const
role_id
=
this
.
activeInfo
.
role_info
.
value
// 直接处理activeInfo对象,避免不必要的数组包装和map操作
const
activeInfo
=
this
.
activeInfo
let
level_attribute
=
[]
try
{
// 安全地访问嵌套属性
if
(
this
.
giftInfo
?.
rule
?.
gift_type
===
1
)
{
level_attribute
=
this
.
giftInfo
.
rule
.
level_attribute
||
[]
}
else
if
(
this
.
giftInfo
?.
rule
?.
level_attribute
)
{
// 过滤出可申请的等级属性
level_attribute
=
this
.
giftInfo
.
rule
.
level_attribute
.
filter
(
item
=>
item
.
apply_num
>
0
)
}
}
catch
(
error
)
{
console
.
error
(
'处理礼包等级属性时出错:'
,
error
)
// 出错时保持level_attribute为空数组
}
// 构建规则数据
const
rule
=
[{
level_attribute
,
id
:
activeInfo
.
id
}]
const
data
=
{
role_id
:
role_id
,
recharge_date
:
''
,
remark
:
this
.
remark
,
create_user
:
this
.
name
,
task_id
:
this
.
task_id
||
null
,
right_type
:
this
.
activeInfo
.
right_type
||
''
,
select_type
:
this
.
activeInfo
.
gift_type
==
7
?
2
:
''
,
rule
:
rule
}
giftBagApply
(
data
).
then
(
res
=>
{
this
.
loading
=
false
if
(
res
.
status_code
===
1
)
{
this
.
$message
.
success
(
res
.
msg
)
this
.
close
()
this
.
$emit
(
'close'
)
}
else
{
this
.
close
()
}
},
err
=>
{
this
.
loading
=
false
})
},
async
submitGift
()
{
this
.
btnLoading
=
true
const
data
=
{
role_id
:
this
.
giftInfo
.
role_id
,
...
...
src/views/components/taskList/SendEmailDialog.vue
0 → 100644
浏览文件 @
a96af5d6
<!--
* @Description: 发送邮件弹窗组件
* @Date: 2025-10-15
-->
<
template
>
<el-dialog
:visible
.
sync=
"dialogVisible"
title=
"发送邮件"
width=
"300px"
:close-on-click-modal=
"false"
:before-close=
"handleClose"
append-to-body
>
<el-form
ref=
"emailForm"
:model=
"formData"
:rules=
"formRules"
label-width=
"80px"
class=
"email-form"
>
<el-form-item
label=
"邮件标题:"
prop=
"email_title"
>
<el-input
v-model=
"formData.email_title"
placeholder=
"请输入邮件标题"
maxlength=
"100"
show-word-limit
clearable
/>
</el-form-item>
<el-form-item
label=
"邮件内容:"
prop=
"email_content"
>
<el-input
v-model=
"formData.email_content"
type=
"textarea"
:rows=
"8"
placeholder=
"请输入邮件内容"
maxlength=
"1000"
show-word-limit
clearable
/>
</el-form-item>
</el-form>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
size=
"small"
@
click=
"handleClose"
>
取消
</el-button>
<el-button
type=
"primary"
:loading=
"sending"
@
click=
"handleConfirm"
size=
"small"
>
确定
</el-button>
</div>
</el-dialog>
</
template
>
<
script
>
import
{
sendEmail
}
from
'@/api/game'
export
default
{
name
:
'SendEmailDialog'
,
props
:
{
// 控制弹窗显示
visible
:
{
type
:
Boolean
,
default
:
false
},
// 任务ID
taskId
:
{
type
:
[
String
,
Number
],
required
:
true
}
},
data
()
{
return
{
// 弹窗显示状态
dialogVisible
:
false
,
// 发送中状态
sending
:
false
,
// 表单数据
formData
:
{
email_title
:
''
,
email_content
:
''
},
// 表单验证规则
formRules
:
{
email_title
:
[
{
required
:
true
,
message
:
'请输入邮件标题'
,
trigger
:
'blur'
},
{
min
:
1
,
max
:
100
,
message
:
'邮件标题长度在 1 到 100 个字符'
,
trigger
:
'blur'
}
],
email_content
:
[
{
required
:
true
,
message
:
'请输入邮件内容'
,
trigger
:
'blur'
},
{
min
:
1
,
max
:
1000
,
message
:
'邮件内容长度在 1 到 1000 个字符'
,
trigger
:
'blur'
}
]
}
}
},
watch
:
{
visible
(
val
)
{
this
.
dialogVisible
=
val
if
(
!
val
)
{
// 关闭时重置表单
this
.
resetForm
()
}
}
},
methods
:
{
/**
* 关闭弹窗
*/
handleClose
()
{
this
.
dialogVisible
=
false
this
.
$emit
(
'update:visible'
,
false
)
this
.
resetForm
()
},
/**
* 重置表单
*/
resetForm
()
{
this
.
formData
=
{
email_title
:
''
,
email_content
:
''
}
// 清除表单验证
this
.
$nextTick
(()
=>
{
this
.
$refs
.
emailForm
&&
this
.
$refs
.
emailForm
.
clearValidate
()
})
},
/**
* 确认发送邮件
*/
handleConfirm
()
{
// 表单验证
this
.
$refs
.
emailForm
.
validate
((
valid
)
=>
{
if
(
valid
)
{
this
.
sendEmailRequest
()
}
else
{
console
.
log
(
'表单验证失败'
)
return
false
}
})
},
/**
* 发送邮件请求
*/
async
sendEmailRequest
()
{
try
{
this
.
sending
=
true
const
params
=
{
id
:
this
.
taskId
,
email_title
:
this
.
formData
.
email_title
,
email_content
:
this
.
formData
.
email_content
}
const
res
=
await
sendEmail
(
params
)
if
(
res
.
status_code
===
1
)
{
this
.
$message
({
message
:
res
.
msg
||
'邮件发送成功'
,
type
:
'success'
})
// 通知父组件发送成功
this
.
$emit
(
'send-success'
)
// 关闭弹窗
this
.
handleClose
()
}
}
catch
(
error
)
{
console
.
error
(
'发送邮件失败:'
,
error
)
}
finally
{
this
.
sending
=
false
}
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.email-form
{
::v-deep
.el-form-item
{
margin-bottom
:
22px
;
}
::v-deep
.el-textarea__inner
{
resize
:
vertical
;
font-family
:
inherit
;
}
::v-deep
.el-input__count
{
background-color
:
transparent
;
}
}
.dialog-footer
{
text-align
:
right
;
padding
:
10px
20px
0
;
border
:
none
;
.el-button
{
min-width
:
80px
;
}
}
</
style
>
src/views/components/taskList/taskDetails.vue
浏览文件 @
a96af5d6
...
...
@@ -184,16 +184,34 @@
</div>
</div>
</div>
<!-- 发送邮件按钮 -->
<!-- -->
<el-button
v-if=
"
kfhList.length == 0 && taskDetails.status != 3 && !is_finished
"
v-if=
"kfhList.length == 0 && assionInfo?.email?.is_send_email == 1 && !assionInfo?.email?.send_status && assionInfo.status != 3"
type=
"primary"
size=
"small"
style=
"margin-top: 20px; margin-right: 10px"
@
click=
"showEmailDialog = true"
>
发送邮件
</el-button>
<!-- 礼包申请按钮 单日申请礼包任务和累充礼包申请时显示 -->
<!-- v-if="(assionInfo.plan_type == 19 || assionInfo.plan_type == 21) && assionInfo.status != 3" -->
<el-button
v-if=
"(assionInfo.plan_type == 19 || assionInfo.plan_type == 21) && assionInfo.status != 3"
type=
"primary"
size=
"small"
style=
"margin-top: 20px; margin-right: 10px"
:loading=
"loading"
@
click=
"giftApply()"
>
礼包申请
</el-button>
<!-- 完成任务按钮 -->
<el-button
v-if=
"kfhList.length == 0 && taskDetails.status != 3 && !is_finished"
type=
"primary"
size=
"small"
style=
"margin-top: 20px"
@
click=
"showLayer = true"
>
完成任务
</el-button
>
>
完成任务
</el-button>
</div>
</div>
</el-drawer>
...
...
@@ -249,7 +267,10 @@
</el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"备注:"
prop=
"remark"
>
<el-form-item
label=
"备注:"
prop=
"remark"
>
<el-input
v-model=
"webForm.remark"
type=
"textarea"
...
...
@@ -257,30 +278,53 @@
placeholder=
"备注请填写异常原因和异常类型,并列举后续维护策略/难以维护的原因"
></el-input>
</el-form-item>
</el-form>
</div>
</layer>
</div>
</
template
>
<
script
>
import
{
mapState
,
mapMutations
}
from
'vuex'
;
import
{
<!-- 发送邮件弹窗 -->
<SendEmailDialog
:visible
.
sync=
"showEmailDialog"
:task-id=
"assionInfo.id"
@
send-success=
"handleEmailSendSuccess"
/>
<!-- 礼包申请弹窗 -->
<applyGift
v-if=
"showApplyGift"
:show
.
sync=
"showApplyGift"
:member_id=
"assionInfo.member_id"
title=
"礼包申请"
width=
"25%"
:task_id=
"task_id"
@
requestData=
"handleGiftApplySuccess"
/>
</div>
</
template
>
<
script
>
import
{
mapState
,
mapMutations
}
from
'vuex'
import
{
taskRecord
,
searchcondition
,
memberOrder
,
RoleTodayOrder
,
taskDetails
,
taskTrack
,
}
from
'@/api/game'
;
import
{
memberBindExternalUser
,
clientSessionBindTaskApi
}
from
'@/api/works'
;
import
layer
from
'@/components/dialog.vue'
;
export
default
{
}
from
'@/api/game'
import
{
memberBindExternalUser
}
from
'@/api/works'
import
layer
from
'@/components/dialog.vue'
import
SendEmailDialog
from
'./SendEmailDialog.vue'
import
applyGift
from
'@/views/components/giftRecord/applyGift.vue'
export
default
{
computed
:
{
...
mapState
(
'game'
,
[
'taskDetails'
]),
...
mapState
(
'user'
,
[
'userInfo'
,
'userid'
]),
...
mapState
(
'user'
,
[
'userInfo'
])
},
components
:
{
layer
,
SendEmailDialog
,
applyGift
},
props
:
[
'show'
],
data
()
{
...
...
@@ -296,20 +340,23 @@ export default {
assionInfo
:
{},
current
:
0
,
showLayer
:
false
,
showEmailDialog
:
false
,
// 控制发送邮件弹窗显示
showApplyGift
:
false
,
// 控制礼包申请弹窗显示
task_id
:
null
,
// 礼包申请任务ID
dialogRemake
:
''
,
webForm
:
{
trace_result
:
''
,
remark
:
''
,
abnormal_types
:
[],
abnormal_types
:
[]
},
webFormRule
:
{
remark
:
[{
required
:
true
,
message
:
'请输入备注'
,
trigger
:
'blur'
}],
trace_result
:
[
{
required
:
true
,
message
:
'请选择跟进结果'
,
trigger
:
'change'
},
{
required
:
true
,
message
:
'请选择跟进结果'
,
trigger
:
'change'
}
],
abnormal_types
:
[
{
required
:
true
,
message
:
'请选择异常原因'
,
trigger
:
'change'
},
],
{
required
:
true
,
message
:
'请选择异常原因'
,
trigger
:
'change'
}
]
},
detailsList
:
[
{
label
:
'游戏名称'
,
value
:
'main_game_name'
},
...
...
@@ -469,63 +516,90 @@ export default {
console
.
log
(
res
,
'打开会话窗口成功'
);
},
fail
:
(
err
)
=>
{
console
.
log
(
err
,
'打开会话窗口失败'
)
;
}
,
})
;
console
.
log
(
err
,
'打开会话窗口失败'
)
}
})
},
async
memberOrder
()
{
let
res
=
{};
let
res
=
{}
if
(
!
this
.
taskDetails
.
cp_role_id
||
this
.
taskDetails
.
cp_role_id
==
''
)
{
res
=
await
memberOrder
({
member_id
:
this
.
taskDetails
.
member_id
});
res
=
await
memberOrder
({
member_id
:
this
.
taskDetails
.
member_id
})
}
else
{
res
=
await
RoleTodayOrder
({
role_id
:
this
.
taskDetails
.
role_id
});
res
=
await
RoleTodayOrder
({
role_id
:
this
.
taskDetails
.
role_id
})
}
this
.
todayOrder
=
res
.
data
[
0
];
this
.
assionInfo
=
{
...
this
.
assionInfo
,
...
this
.
todayOrder
};
this
.
todayOrder
=
res
.
data
[
0
]
this
.
assionInfo
=
{
...
this
.
assionInfo
,
...
this
.
todayOrder
}
},
async
taskRecord
()
{
const
res
=
await
taskRecord
({
task_id
:
this
.
taskDetails
.
id
,
user_type
:
''
,
});
console
.
log
(
res
.
data
.
data
,
'res.data.data'
);
if
(
res
.
data
.
data
.
length
>
0
)
{
this
.
remarks
=
res
.
data
.
data
[
0
].
remarks
;
}
else
{
this
.
remarks
=
[{
remark
:
''
}];
const
res
=
await
taskRecord
({
task_id
:
this
.
taskDetails
.
id
,
user_type
:
''
})
console
.
log
(
res
.
data
.
data
,
'res.data.data'
)
if
(
res
.
data
.
data
.
length
>
0
){
this
.
remarks
=
res
.
data
.
data
[
0
].
remarks
}
else
{
this
.
remarks
=
[{
remark
:
''
}]
}
},
async
memberBindExternalUser
()
{
let
member_list
=
[];
let
member_list
=
[]
if
(
this
.
assionInfo
.
members
?.
length
>
0
)
{
member_list
=
this
.
assionInfo
.
members
.
map
((
item
)
=>
item
.
member_id
);
member_list
=
this
.
assionInfo
.
members
.
map
((
item
)
=>
item
.
member_id
)
}
else
{
member_list
=
[
this
.
assionInfo
.
member_id
];
member_list
=
[
this
.
assionInfo
.
member_id
]
}
this
.
loading
=
true
;
this
.
loading
=
true
if
(
member_list
.
length
===
0
)
{
return
false
;
return
false
}
try
{
const
res
=
await
memberBindExternalUser
({
member_id
:
member_list
.
toString
(),
is_bind
:
this
.
assionInfo
.
is_bind
,
});
this
.
kfhList
=
res
.
data
;
this
.
loading
=
false
;
is_bind
:
this
.
assionInfo
.
is_bind
})
this
.
kfhList
=
res
.
data
this
.
loading
=
false
}
catch
(
error
)
{
this
.
loading
=
false
;
this
.
loading
=
false
}
},
/**
* 处理邮件发送成功的回调
* 设置任务的邮件发送状态为已发送
*/
handleEmailSendSuccess
()
{
// 标记任务已发送邮件
this
.
assionInfo
.
send_status
=
1
// 可以选择刷新任务详情
// this.requestTaskDetails()
},
};
</
script
>
/**
* 显示礼包申请弹窗
* @param {Object} item - 任务信息对象,包含任务ID
*/
giftApply
()
{
this
.
task_id
=
this
.
assionInfo
.
id
||
null
this
.
showApplyGift
=
true
},
/**
* 处理礼包申请完成后的回调
* 关闭弹窗并显示成功提示
*/
handleGiftApplySuccess
()
{
this
.
showApplyGift
=
false
this
.
$message
({
message
:
'礼包申请已提交'
,
type
:
'success'
})
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.contet
{
height
:
100%
;
background
:
#fff
;
padding
:
10px
;
overflow
:
auto
;
.title
{
font-size
:
14px
;
...
...
@@ -534,7 +608,6 @@ export default {
color
:
#333333
;
margin-bottom
:
10px
;
}
.taskInfo
{
height
:
auto
;
background
:
#f7f8fa
;
...
...
src/views/components/taskList/uesrTask.vue
浏览文件 @
a96af5d6
...
...
@@ -76,9 +76,11 @@
</div>
</div>
<div
class=
"btns rowFlex allCenter"
style=
"margin-top: 20px"
>
<el-button
:disabled=
"item.status == 3"
:loading=
"remarkLoading"
<el-button
size=
"small"
:disabled=
"item.status == 3"
:loading=
"remarkLoading"
@
click=
"saveRemak(item, index)"
>
保存
</el-button>
<el-button
type=
"primary"
:disabled=
"item.status == 3"
:loading=
"taskLoading"
<!-- 单日申请礼包任务才展示礼包申请按钮 v-if="item.plan_type == 19 || item.plan_type == 21" 新增 累充礼包申请时 和 单日礼包申请一样 显示 礼包申请按钮 -->
<el-button
type=
"primary"
size=
"small"
v-if=
"item.plan_type == 19 || item.plan_type == 21"
:loading=
"taskLoading"
@
click=
"giftApply(item)"
>
礼包申请
</el-button>
<el-button
type=
"primary"
size=
"small"
:disabled=
"item.status == 3"
:loading=
"taskLoading"
@
click=
"completeTask(item, index)"
>
保存并完成任务
</el-button>
</div>
</el-collapse-item>
...
...
@@ -92,6 +94,15 @@
</div>
</div>
</div>
<!-- 礼包申请弹窗 -->
<applyGift
v-if=
"showApplyGift"
:show
.
sync=
"showApplyGift"
title=
"礼包申请"
width=
"25%"
:task_id=
"task_id"
@
requestData=
"handleGiftApplySuccess"
/>
</div>
</template>
<
script
>
...
...
@@ -99,10 +110,12 @@
import
{
mapState
}
from
'vuex'
import
textEditor
from
'@/components/textEditor.vue'
import
noContent
from
'@/components/noContent.vue'
import
applyGift
from
'@/views/components/giftRecord/applyGift.vue'
export
default
{
components
:
{
textEditor
,
noContent
,
applyGift
},
data
()
{
return
{
...
...
@@ -131,6 +144,8 @@
showLayer
:
false
,
taskLoading
:
false
,
remarkLoading
:
false
,
showApplyGift
:
false
,
task_id
:
null
,
pageInfo
:
{
page
:
0
,
page_size
:
20
,
...
...
@@ -190,6 +205,24 @@
this
.
searchconditionError
()
},
methods
:
{
/**
* 显示礼包申请弹窗
*/
giftApply
(
item
)
{
this
.
task_id
=
item
.
id
||
null
this
.
showApplyGift
=
true
},
/**
* 处理礼包申请完成后的回调
* 关闭弹窗并显示成功提示
*/
handleGiftApplySuccess
()
{
this
.
showApplyGift
=
false
this
.
$message
({
message
:
'礼包申请已提交'
,
type
:
'success'
})
},
searchcondition
()
{
const
data
=
{
type
:
'dictionaries'
,
...
...
src/views/userInfo/components/gameInfo/benefitusageRecord.vue
0 → 100644
浏览文件 @
a96af5d6
<!--
* @Author: maoxiya 937667504@qq.com
* @Date: 2025-10-31 15:00:00
* @LastEditors: maoxiya 937667504@qq.com
* @LastEditTime: 2025-10-31 17:18:17
* @FilePath: /company_wx_frontend/src/components/common/game/benefitUsageRecord.vue
* @Description: 权益使用记录组件
-->
<
template
>
<div
class=
"benefit-usage-record"
>
<!-- 搜索区域 -->
<div
class=
"search-content"
>
<el-form
label-position=
"top"
:model=
"formData"
class=
"search-form"
>
<el-form-item
label=
"权益"
>
<el-select
v-model=
"formData.type"
clearable
placeholder=
"请选择权益"
@
change=
"handleTypeChange"
style=
"width:100%;"
>
<el-option
v-for=
"item in benefitOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"时间范围"
>
<el-date-picker
v-model=
"formData.dateRange"
type=
"datetimerange"
format=
"yyyy-MM-dd HH:mm:ss"
value-format=
"yyyy-MM-dd HH:mm:ss"
range-separator=
"至"
start-placeholder=
"开始时间"
end-placeholder=
"结束时间"
clearable
:default-time=
"['00:00:00', '23:59:59']"
style=
"width:100%;"
/>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
:loading=
"loading"
@
click=
"startSearch"
>
搜索
</el-button>
<el-button
@
click=
"resetForm"
>
重置
</el-button>
</el-form-item>
</el-form>
</div>
<!-- 表格区域 -->
<div
class=
"table-container"
>
<el-table
v-loading=
"loading"
:data=
"tableData"
style=
"width: 100%"
:header-cell-style=
"
{ background: '#f5f7fa', color: '#606266' }"
>
<el-table-column
label=
"角色名称/cp角色Id"
min-width=
"200"
>
<template
slot-scope=
"scope"
>
<p>
{{
scope
.
row
.
role_name
}}
</p>
<p
class=
"infoText"
>
{{
scope
.
row
.
cp_role_id
}}
</p>
</
template
>
</el-table-column>
<el-table-column
label=
"权益"
prop=
"type_name"
min-width=
"150"
/>
<el-table-column
label=
"使用人"
prop=
"create_user"
min-width=
"120"
/>
<el-table-column
label=
"使用时间"
prop=
"create_time"
min-width=
"180"
/>
</el-table>
<!-- 分页 -->
<div
class=
"pagination-container"
>
<el-pagination
@
current-change=
"handleCurrentChange"
@
size-change=
"handleSizeChange"
:current-page=
"page_info.page"
:page-sizes=
"[10, 20, 50, 100]"
:page-size=
"page_info.page_size"
layout=
"total, sizes, prev, pager, next, jumper"
:total=
"page_info.total"
/>
</div>
</div>
</div>
</template>
<
script
>
import
{
useRightList
,
selectSearch
}
from
'@/api/game'
export
default
{
name
:
'BenefitUsageRecord'
,
props
:
{
benefitItem
:
{
type
:
Object
,
default
:
()
=>
({})
},
roleInfo
:
{
type
:
Object
,
default
:
()
=>
({})
}
},
data
()
{
return
{
loading
:
false
,
formData
:
{
type
:
''
,
dateRange
:
[]
},
benefitOptions
:
[],
tableData
:
[],
tableColums
:
[
{
label
:
'角色名称/cp角色Id'
,
prop
:
'role_info'
,
minWidth
:
200
,
slotScope
:
true
},
{
label
:
'权益'
,
prop
:
'type_name'
,
minWidth
:
150
},
{
label
:
'使用人'
,
prop
:
'create_user'
,
minWidth
:
120
,
},
{
label
:
'使用时间'
,
prop
:
'create_time'
,
minWidth
:
180
}
],
page_info
:
{
page
:
1
,
page_size
:
20
,
total
:
0
}
}
},
mounted
()
{
this
.
getBenefitOptions
()
this
.
getTableData
()
},
methods
:
{
/**
* 获取权益下拉选项
*/
async
getBenefitOptions
()
{
try
{
const
data
=
{
type
:
'svip_right'
,
}
const
res
=
await
selectSearch
(
data
)
if
(
res
.
status_code
===
1
&&
res
.
data
&&
res
.
data
.
data
&&
res
.
data
.
data
.
length
>
0
)
{
this
.
benefitOptions
=
res
.
data
.
data
}
}
catch
(
error
)
{
console
.
error
(
'获取权益选项失败:'
,
error
)
}
},
/**
* 获取表格数据
*/
async
getTableData
()
{
try
{
this
.
loading
=
true
const
requestData
=
{
cp_role_id
:
this
.
roleInfo
.
cp_role_id
,
type
:
this
.
formData
.
type
,
create_time_start
:
this
.
formData
.
dateRange
&&
this
.
formData
.
dateRange
.
length
>
0
?
this
.
formData
.
dateRange
[
0
]
:
''
,
create_time_end
:
this
.
formData
.
dateRange
&&
this
.
formData
.
dateRange
.
length
>
0
?
this
.
formData
.
dateRange
[
1
]
:
''
,
page
:
this
.
page_info
.
page
,
page_size
:
this
.
page_info
.
page_size
}
const
res
=
await
useRightList
(
requestData
)
if
(
res
.
status_code
===
1
)
{
this
.
tableData
=
res
.
data
.
data
||
[]
this
.
page_info
.
total
=
Number
(
res
.
data
.
page_info
.
total
)
||
0
}
else
{
this
.
$message
({
message
:
res
.
data
.
msg
||
'获取数据失败'
,
type
:
'error'
})
}
}
catch
(
error
)
{
console
.
error
(
'获取权益使用记录失败:'
,
error
)
this
.
$message
({
message
:
'获取数据失败,请重试'
,
type
:
'error'
})
}
finally
{
this
.
loading
=
false
}
},
/**
* 处理页码变化
*/
handleCurrentChange
(
currentPage
)
{
this
.
page_info
.
page
=
currentPage
this
.
getTableData
()
},
/**
* 处理每页条数变化
*/
handleSizeChange
(
pageSize
)
{
this
.
page_info
.
page_size
=
pageSize
this
.
page_info
.
page
=
1
this
.
getTableData
()
},
/**
* 处理权益类型变化
*/
handleTypeChange
()
{
this
.
page_info
.
page
=
1
this
.
getTableData
()
},
/**
* 开始搜索
*/
startSearch
()
{
this
.
page_info
.
page
=
1
this
.
getTableData
()
},
/**
* 重置表单
*/
resetForm
()
{
this
.
formData
=
{
type
:
''
,
dateRange
:
[]
}
this
.
startSearch
()
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.benefit-usage-record
{
::v-deep
.el-table__header-wrapper{
position
:
static
;
top
:
0
;
}
.search-content
{
padding
:
20px
;
background
:
#fff
;
border-radius
:
4px
;
max-height
:
80%
;
overflow
:
auto
;
.search-form
{
.el-form-item
{
margin-bottom
:
16px
;
&:last-child
{
margin-bottom
:
0
;
}
}
}
}
.table-container
{
background
:
#fff
;
border-radius
:
4px
;
padding
:
20px
;
}
.pagination-container
{
margin-top
:
20px
;
text-align
:
right
;
}
.infoText
{
color
:
#c9cdd4
;
font-size
:
12px
;
margin-top
:
4px
;
}
}
</
style
>
src/views/userInfo/components/gameInfo/vipLevel.vue
浏览文件 @
a96af5d6
...
...
@@ -2,7 +2,7 @@
* @Author: maoxiya 937667504@qq.com
* @Date: 2025-09-13 14:05:01
* @LastEditors: maoxiya 937667504@qq.com
* @LastEditTime: 2025-
09-22 17:24:19
* @LastEditTime: 2025-
10-31 17:01:13
* @FilePath: /company_wx_frontend/src/views/works/component/gameInfo/vipLevel.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
...
...
@@ -16,7 +16,7 @@
:disabled=
"loading"
>
<!-- 最大宽度 400px -->
<div
class=
"vipLevelContent"
style=
"m
ax-width: 400px;max-height: 300px;overflow: auto
;"
>
<div
class=
"vipLevelContent"
style=
"m
in-width:250px
;"
>
<div
v-if=
"loading"
class=
"loading-content"
>
<i
class=
"el-icon-loading"
></i>
<span>
加载中...
</span>
...
...
@@ -25,7 +25,19 @@
<div
class=
"vipLevelItem rowFlex columnCenter"
v-for=
"(item,index) in vipLevelBenefit"
:key=
"index"
>
<p
class=
"vipLevelItemRow"
v-if=
"item.num"
:style=
"
{color: item.target ? '#333333' : '#c9cdd4'}" >
<span
v-if=
"item.name"
class=
"label"
>
{{
item
.
name
}}
</span>
<span
v-if=
"item.num"
:style=
"
{color: item.target ? '#00bf8a' : '#c9cdd4'}" class="value">
{{
item
.
num
}}
次
</span>
<!-- 人工权益显示使用按钮 -->
<div
v-if=
"item.monitor_type === 2"
class=
"benefit-actions"
>
<el-button
type=
"primary"
size=
"mini"
style=
"margin-left: 10px;"
:disabled=
"!item.target"
@
click
.
stop=
"handleUseBenefit(item)"
class=
"use-button"
>
使用
</el-button>
</div>
</p>
</div>
<div
v-if=
"vipLevelBenefit.length === 0"
class=
"no-data"
>
...
...
@@ -37,11 +49,62 @@
<span
class=
"vipLevelText"
v-if=
"vip_role_info.vip_level"
@
click
.
stop=
"showVipLevel"
>
{{
`SVIP等级${vip_role_info.vip_level
}
`
}}
<
/span
>
<
/div
>
<
/el-popover
>
<!--
使用权益确认弹窗
-->
<
el
-
dialog
v
-
if
=
"useBenefitDialogVisible"
title
=
"确认提示"
:
visible
.
sync
=
"useBenefitDialogVisible"
width
=
"400px"
:
before
-
close
=
"handleDialogClose"
>
<
div
class
=
"dialog-content"
>
<
div
class
=
"rowFlex columnCenter"
>
<
i
class
=
"el-icon-warning"
style
=
"color: #E6A23C; font-size: 24px; margin-right: 10px;"
><
/i
>
<
span
>
是否确认使用
{{
currentBenefitItem
?.
name
}}
权益?
<
/span
>
<
/div
>
<
p
class
=
"text-center"
style
=
"color: #999; font-size: 14px; margin-top: 10px;"
>
点击确定后
,
权益剩余使用数量将减
1
<
/p
>
<
/div
>
<
div
slot
=
"footer"
>
<
el
-
button
type
=
"text"
@
click
=
"showUsageRecordFromDialog"
class
=
"record-button"
>
使用记录
<
/el-button
>
<
el
-
button
@
click
=
"handleDialogClose"
>
取消
<
/el-button
>
<
el
-
button
type
=
"primary"
:
loading
=
"loading"
@
click
=
"confirmUseBenefit"
>
确认
<
/el-button
>
<
/div
>
<
/el-dialog
>
<!--
使用记录弹窗
-->
<
el
-
dialog
title
=
"权益使用记录"
:
visible
.
sync
=
"usageRecordVisible"
width
=
"80%"
:
before
-
close
=
"closeUsageRecord"
append
-
to
-
body
@
close
=
"closeUsageRecord"
>
<
BenefitUsageRecord
:
benefit
-
item
=
"currentBenefitItem"
:
role
-
info
=
"vip_role_info"
/>
<
/el-dialog
>
<
/div
>
<
/template
>
<
script
>
import
{
marketingRoleGradeBenefit
,
marketingMemberRoleGrade
}
from
'@/api/game'
import
{
marketingRoleGradeBenefit
,
marketingMemberRoleGrade
,
useBenefit
}
from
'@/api/game'
import
{
mapState
,
mapMutations
}
from
'vuex'
import
BenefitUsageRecord
from
'./benefitusageRecord.vue'
export
default
{
name
:
'VipLevel'
,
data
()
{
...
...
@@ -49,9 +112,15 @@ export default {
vip_role_info
:
{
}
,
vipLevelBenefit
:
[],
popoverVisible
:
false
,
loading
:
false
loading
:
false
,
usageRecordVisible
:
false
,
currentBenefitItem
:
null
,
useBenefitDialogVisible
:
false
}
}
,
components
:
{
BenefitUsageRecord
}
,
props
:
{
roleInfo
:
{
type
:
Object
,
...
...
@@ -73,7 +142,8 @@ export default {
}
}
,
computed
:
{
...
mapState
(
'game'
,
[
'accountSelect'
])
...
mapState
(
'game'
,
[
'accountSelect'
]),
...
mapState
(
'user'
,
[
'userInfo'
]),
}
,
methods
:
{
async
marketingMemberRoleGrade
()
{
...
...
@@ -134,7 +204,80 @@ export default {
// 获取数据并显示popover
await
this
.
getVipLevel
();
}
,
/**
* 处理使用权益
*/
handleUseBenefit
(
item
)
{
this
.
currentBenefitItem
=
item
;
this
.
useBenefitDialogVisible
=
true
;
}
,
/**
* 确认使用权益
*/
async
confirmUseBenefit
()
{
try
{
this
.
loading
=
true
;
const
requestData
=
{
role_id
:
this
.
vip_role_info
.
role_id
,
grade_config_id
:
this
.
currentBenefitItem
.
grade_config_id
,
user_name
:
this
.
userInfo
.
username
}
;
const
res
=
await
useBenefit
(
requestData
);
if
(
res
.
status_code
===
1
)
{
this
.
$message
({
message
:
res
.
data
.
msg
||
'使用成功'
,
type
:
'success'
}
);
// 直接更新本地权益数据
const
benefitIndex
=
this
.
vipLevelBenefit
.
findIndex
(
item
=>
item
.
grade_config_id
===
this
.
currentBenefitItem
.
grade_config_id
);
if
(
benefitIndex
!==
-
1
)
{
this
.
vipLevelBenefit
[
benefitIndex
].
remain_num
-=
1
;
}
this
.
useBenefitDialogVisible
=
false
;
this
.
currentBenefitItem
=
null
;
}
else
{
this
.
$message
({
message
:
res
.
data
.
msg
||
'使用失败'
,
type
:
'error'
}
);
}
}
catch
(
error
)
{
console
.
error
(
'使用权益失败:'
,
error
);
}
finally
{
this
.
loading
=
false
;
}
}
,
/**
* 处理dialog关闭
*/
handleDialogClose
()
{
this
.
useBenefitDialogVisible
=
false
;
this
.
currentBenefitItem
=
null
;
}
,
/**
* 从dialog中显示使用记录弹窗
*/
showUsageRecordFromDialog
()
{
this
.
usageRecordVisible
=
true
;
this
.
useBenefitDialogVisible
=
false
;
}
,
/**
* 关闭使用记录弹窗
*/
closeUsageRecord
()
{
this
.
usageRecordVisible
=
false
;
this
.
currentBenefitItem
=
null
;
}
}
}
<
/script
>
...
...
@@ -185,8 +328,54 @@ export default {
.
value
{
font
-
weight
:
bold
;
}
.
benefit
-
actions
{
display
:
flex
;
align
-
items
:
center
;
gap
:
8
px
;
margin
-
left
:
auto
;
.
use
-
button
{
margin
-
left
:
10
px
;
}
.
record
-
button
{
font
-
size
:
12
px
;
padding
:
0
;
}
}
}
}
}
.
dialog
-
content
{
font
-
size
:
16
px
;
color
:
#
333
;
}
.
dialog
-
footer
{
display
:
flex
;
justify
-
content
:
flex
-
end
;
align
-
items
:
center
;
.
record
-
button
{
margin
-
left
:
10
px
;
color
:
#
409
EFF
;
cursor
:
pointer
;
&
:
hover
{
color
:
#
66
b1ff
;
}
}
}
// 使用记录弹窗样式
.
el
-
dialog
{
::
v
-
deep
.
el
-
dialog__body
{
padding
:
0
;
max
-
height
:
70
vh
;
overflow
-
y
:
auto
;
}
}
}
<
/style>
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论