Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
4655fb4b
authored
Jul 14, 2026
by
renyizhao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
用户资源包列表修改
parent
0bf3c8de
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
120 additions
and
93 deletions
+120
-93
src/api/apihub/userapiusage/index.ts
+2
-0
src/views/apihub/api/ApiForm.vue
+48
-80
src/views/apihub/userapiusage/UserApiUsageDetail.vue
+46
-0
src/views/apihub/userapiusage/index.vue
+24
-13
No files found.
src/api/apihub/userapiusage/index.ts
View file @
4655fb4b
...
...
@@ -5,6 +5,8 @@ import type { Dayjs } from 'dayjs';
export
interface
UserApiUsage
{
id
:
number
;
// 记录ID
userId
?:
number
;
// 用户ID
userMobile
?:
string
;
// 用户手机号
userNickname
?:
string
;
// 用户昵称
apiId
?:
number
;
// API ID
apiName
?:
string
;
// api名称
packageId
?:
number
;
// 购买的套餐ID
...
...
src/views/apihub/api/ApiForm.vue
View file @
4655fb4b
...
...
@@ -15,13 +15,8 @@
</el-form-item>
<!-- 分类选择 -->
<el-form-item
label=
"分类"
prop=
"categoryId"
>
<el-select
v-model=
"formData.categoryId"
placeholder=
"请选择分类"
style=
"width: 100%;"
>
<el-option
v-for=
"c in categoryList"
:key=
"c.id"
:label=
"c.name"
:value=
"c.id"
/>
<el-select
v-model=
"formData.categoryId"
placeholder=
"请选择分类"
style=
"width: 100%"
>
<el-option
v-for=
"c in categoryList"
:key=
"c.id"
:label=
"c.name"
:value=
"c.id"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"API供应商"
prop=
"vendor"
>
...
...
@@ -32,10 +27,8 @@
</el-form-item>
<el-form-item
label=
"关联接口"
>
<!-- 添加接口按钮独占一行 -->
<div
style=
"margin-bottom: 10px;"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"addApiEndpoint"
>
添加接口
</el-button>
<div
style=
"margin-bottom: 10px"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"addApiEndpoint"
>
添加接口
</el-button>
</div>
<!-- 接口表格,每个接口占一行 -->
...
...
@@ -80,7 +73,6 @@
</table>
</el-form-item>
<el-form-item
label=
"API 简介"
prop=
"description"
>
<el-input
v-model=
"formData.description"
height=
"350px"
/>
</el-form-item>
...
...
@@ -115,7 +107,7 @@
<el-form-item
label=
"资源包配置"
prop=
"apiPackages"
>
<el-button
type=
"primary"
@
click=
"addApiPackages"
>
新增
</el-button>
<div
style=
"padding-top: 10px
;
"
>
<div
style=
"padding-top: 10px"
>
<table
class=
"table"
>
<thead>
<tr>
...
...
@@ -159,7 +151,10 @@
</el-form-item>
</td>
<td>
<el-form-item
:prop=
"'apiPackages.' + index + '.validDays'"
:rules=
"rules.validDays"
>
<el-form-item
:prop=
"'apiPackages.' + index + '.validDays'"
:rules=
"rules.validDays"
>
<el-input-number
v-model=
"i.validDays"
:min=
"1"
...
...
@@ -169,19 +164,22 @@
</el-form-item>
</td>
<td>
<el-button
type=
"danger"
:disabled=
"formData.apiPackages.length === 1"
@
click=
"delapiPackage(index)"
>
<el-button
type=
"danger"
:disabled=
"formData.apiPackages.length === 1"
@
click=
"delapiPackage(index)"
>
删除
</el-button>
<!--
<el-button-->
<!-- type="primary"-->
<!-- :disabled="index === 0"-->
<!-- @click="upItem(index)">上移
</el-button>
-->
<!--
<el-button-->
<!-- type="primary"-->
<!-- :disabled="index + 1 === formData.apiPackages.length"-->
<!-- @click="downItem(index)">下移-->
<!--
</el-button>
-->
<!--
<el-button-->
<!-- type="primary"-->
<!-- :disabled="index === 0"-->
<!-- @click="upItem(index)">上移
</el-button>
-->
<!--
<el-button-->
<!-- type="primary"-->
<!-- :disabled="index + 1 === formData.apiPackages.length"-->
<!-- @click="downItem(index)">下移-->
<!--
</el-button>
-->
</td>
</tr>
</tbody>
...
...
@@ -196,11 +194,10 @@
</Dialog>
</template>
<
script
setup
lang=
"ts"
>
import
{
ApiApi
,
Api
,
ApiCategory
}
from
'@/api/apihub/api'
import
{
DICT_TYPE
,
getIntDictOptions
}
from
"@/utils/dict"
import
{
ApiApi
,
Api
,
ApiCategory
}
from
'@/api/apihub/api'
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
import
type
{
FormItemRule
}
from
'element-plus'
import
{
ApiEndpoint
,
ApiEndpointApi
}
from
"@/api/apihub/apiendpoint"
;
import
{
ApiEndpoint
,
ApiEndpointApi
}
from
'@/api/apihub/apiendpoint'
const
categoryList
=
ref
<
ApiCategory
[]
>
([])
...
...
@@ -223,7 +220,6 @@ const dialogTitle = ref('') // 弹窗的标题
const
formLoading
=
ref
(
false
)
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
const
formType
=
ref
(
''
)
// 表单的类型:create - 新增;update - 修改
const
formData
=
ref
({
id
:
undefined
,
name
:
''
,
...
...
@@ -231,23 +227,17 @@ const formData = ref({
categoryId
:
undefined
,
// 新增:分类id
vendor
:
undefined
,
vendorContact
:
undefined
,
priceInfo
:
''
,
priceInfo
:
''
,
coverImage
:
undefined
,
description
:
''
,
detail
:
''
,
doc
:
''
,
status
:
1
,
// 默认上架
remark
:
''
,
apiPackages
:
[
{
name
:
'套餐'
,
times
:
1
,
price
:
1
,
validDays
:
30
,
id
:
null
}
],
apiEndPoints
:
[
{
name
:
'接口'
,
path
:
'https://'
,
method
:
'POST'
,
id
:
null
}
],
apiPackages
:
[{
name
:
'套餐'
,
times
:
1
,
price
:
1
,
validDays
:
30
,
id
:
null
}],
apiEndPoints
:
[{
name
:
'接口'
,
path
:
'https://'
,
method
:
'POST'
,
id
:
null
}]
})
// 自定义校验器
const
validatePrice
:
FormItemRule
[
'validator'
]
=
(
_rule
,
value
,
callback
)
=>
{
if
(
value
===
undefined
||
value
===
null
)
{
...
...
@@ -269,35 +259,25 @@ const validateTimes: FormItemRule['validator'] = (_rule, value, callback) => {
callback
()
}
const
rules
=
reactive
({
name
:
[
{
required
:
true
,
message
:
'请输入套餐名称'
,
trigger
:
[
'blur'
,
'change'
]
}
],
price
:
[
{
required
:
true
,
validator
:
validatePrice
,
trigger
:
[
'blur'
,
'change'
]
}
],
times
:
[
{
required
:
true
,
validator
:
validateTimes
,
trigger
:
[
'blur'
,
'change'
]
}
],
validDays
:
[
{
required
:
true
,
validator
:
validateTimes
,
trigger
:
[
'blur'
,
'change'
]
}
]})
name
:
[{
required
:
true
,
message
:
'请输入套餐名称'
,
trigger
:
[
'blur'
,
'change'
]
}],
price
:
[{
required
:
true
,
validator
:
validatePrice
,
trigger
:
[
'blur'
,
'change'
]
}],
times
:
[{
required
:
true
,
validator
:
validateTimes
,
trigger
:
[
'blur'
,
'change'
]
}],
validDays
:
[{
required
:
true
,
validator
:
validateTimes
,
trigger
:
[
'blur'
,
'change'
]
}]
})
const
formRules
=
reactive
({
categoryId
:
[{
required
:
true
,
message
:
'请选择分类'
,
trigger
:
'change'
}],
name
:
[
{
required
:
true
,
message
:
'请输入名称'
,
trigger
:
[
'blur'
,
'change'
]
}
]})
name
:
[{
required
:
true
,
message
:
'请输入名称'
,
trigger
:
[
'blur'
,
'change'
]
}]
})
const
formRef
=
ref
()
// 表单 Ref
const
addApiPackages
=
()
=>
{
formData
.
value
.
apiPackages
.
push
({
name
:
'套餐'
,
times
:
1
,
price
:
1
,
validDays
:
30
,
id
:
null
});
formData
.
value
.
apiPackages
.
push
({
name
:
'套餐'
,
times
:
1
,
price
:
1
,
validDays
:
30
,
id
:
null
})
}
const
delapiPackage
=
(
index
)
=>
{
formData
.
value
.
apiPackages
.
splice
(
index
,
1
)
;
formData
.
value
.
apiPackages
.
splice
(
index
,
1
)
}
//
// const upItem = (index: number) => {
...
...
@@ -316,8 +296,6 @@ const delapiPackage = (index) => {
// arr[index] = tmp
// }
/** 打开弹窗 */
const
open
=
async
(
type
:
string
,
id
?:
number
)
=>
{
dialogVisible
.
value
=
true
...
...
@@ -335,8 +313,8 @@ const open = async (type: string, id?: number) => {
try
{
// 调用 getApi 后做一次数据清洗
const
res
=
await
ApiApi
.
getApi
(
id
)
res
.
detail
=
res
.
detail
??
""
res
.
doc
=
res
.
doc
??
""
res
.
detail
=
res
.
detail
??
''
res
.
doc
=
res
.
doc
??
''
formData
.
value
=
res
}
finally
{
formLoading
.
value
=
false
...
...
@@ -344,8 +322,6 @@ const open = async (type: string, id?: number) => {
}
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
/** 提交表单 */
...
...
@@ -384,7 +360,7 @@ const resetForm = () => {
formData
.
value
=
{
id
:
undefined
,
categoryId
:
undefined
,
priceInfo
:
''
,
priceInfo
:
''
,
coverImage
:
undefined
,
name
:
''
,
trialUrl
:
''
,
...
...
@@ -393,19 +369,13 @@ const resetForm = () => {
doc
:
''
,
status
:
1
,
remark
:
''
,
apiPackages
:
[
{
name
:
'套餐'
,
times
:
1
,
price
:
1
,
validDays
:
30
,
id
:
null
}
],
apiEndPoints
:
[
{
name
:
'接口'
,
path
:
'https://'
,
method
:
'POST'
,
id
:
null
}
],
apiPackages
:
[{
name
:
'套餐'
,
times
:
1
,
price
:
1
,
validDays
:
30
,
id
:
null
}],
apiEndPoints
:
[{
name
:
'接口'
,
path
:
'https://'
,
method
:
'POST'
,
id
:
null
}]
}
formRef
.
value
?.
resetFields
()
}
// -----------------------------------------------添加接口start----------------------------------------------------------------------------------------
// -----------------------------------------------添加接口start----------------------------------------------------------------------------------------
const
apiEndPointList
=
ref
<
ApiEndpoint
[]
>
([])
...
...
@@ -421,9 +391,9 @@ const getAllApiEndPointsList = async () => {
const
addApiEndpoint
=
()
=>
{
formData
.
value
.
apiEndPoints
.
push
({
id
:
null
,
name
:
""
,
path
:
""
,
method
:
""
name
:
''
,
path
:
''
,
method
:
''
})
}
...
...
@@ -434,7 +404,7 @@ const removeApiEndpoint = (index: number) => {
// 选择接口时自动填充 name、path、method
const
onApiSelected
=
(
id
:
number
,
row
:
any
)
=>
{
const
api
=
apiEndPointList
.
value
.
find
(
item
=>
item
.
id
===
id
)
const
api
=
apiEndPointList
.
value
.
find
(
(
item
)
=>
item
.
id
===
id
)
if
(
api
)
{
row
.
name
=
api
.
name
row
.
path
=
api
.
path
...
...
@@ -442,7 +412,6 @@ const onApiSelected = (id: number, row: any) => {
}
}
// -----------------------------------------------添加接口End---------------------------------------------------------------------------------------
</
script
>
<
style
scoped
>
...
...
@@ -490,5 +459,4 @@ const onApiSelected = (id: number, row: any) => {
padding
:
10px
5px
;
vertical-align
:
middle
;
}
</
style
>
src/views/apihub/userapiusage/UserApiUsageDetail.vue
0 → 100644
View file @
4655fb4b
<
template
>
<el-dialog
title=
"资源包详情"
v-model=
"visible"
width=
"700px"
>
<el-descriptions
:column=
"2"
border
v-loading=
"loading"
>
<el-descriptions-item
label=
"用户手机号"
>
{{
detailData
.
userMobile
||
'-'
}}
</el-descriptions-item>
<el-descriptions-item
label=
"用户昵称"
>
{{
detailData
.
userNickname
||
'-'
}}
</el-descriptions-item>
<el-descriptions-item
label=
"API名称"
>
{{
detailData
.
apiName
||
'-'
}}
</el-descriptions-item>
<el-descriptions-item
label=
"套餐名称"
>
{{
detailData
.
packageName
||
'-'
}}
</el-descriptions-item>
<el-descriptions-item
label=
"套餐总量"
>
{{
detailData
.
packageTimes
??
'-'
}}
</el-descriptions-item>
<el-descriptions-item
label=
"有效时长"
>
{{
detailData
.
packageValidDays
?
detailData
.
packageValidDays
+
' 天'
:
'-'
}}
</el-descriptions-item>
<el-descriptions-item
label=
"已使用次数"
>
{{
detailData
.
usedTimes
??
'-'
}}
</el-descriptions-item>
<el-descriptions-item
label=
"过期时间"
>
{{
formatDate
(
detailData
.
expireTime
)
}}
</el-descriptions-item>
<el-descriptions-item
label=
"购买时间"
>
{{
formatDate
(
detailData
.
createTime
)
}}
</el-descriptions-item>
</el-descriptions>
</el-dialog>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
UserApiUsageApi
}
from
'@/api/apihub/userapiusage'
const
visible
=
ref
(
false
)
const
loading
=
ref
(
false
)
const
detailData
=
ref
<
any
>
({})
const
formatDate
=
(
date
:
string
)
=>
{
if
(
!
date
)
return
'-'
const
d
=
new
Date
(
date
)
if
(
isNaN
(
d
.
getTime
()))
return
date
const
pad
=
(
n
:
number
)
=>
n
.
toString
().
padStart
(
2
,
'0'
)
return
`
${
d
.
getFullYear
()}
-
${
pad
(
d
.
getMonth
()
+
1
)}
-
${
pad
(
d
.
getDate
())}
${
pad
(
d
.
getHours
())}
:
${
pad
(
d
.
getMinutes
())}
:
${
pad
(
d
.
getSeconds
())}
`
}
const
open
=
async
(
id
:
number
)
=>
{
visible
.
value
=
true
loading
.
value
=
true
try
{
const
data
=
await
UserApiUsageApi
.
getUserApiUsage
(
id
)
detailData
.
value
=
data
}
finally
{
loading
.
value
=
false
}
}
defineExpose
({
open
})
</
script
>
src/views/apihub/userapiusage/index.vue
View file @
4655fb4b
...
...
@@ -48,7 +48,7 @@
>
<Icon
icon=
"ep:download"
class=
"mr-5px"
/>
导出
</el-button>
<el-button
<
!--
<
el-button
type=
"danger"
plain
:disabled=
"isEmpty(checkedIds)"
...
...
@@ -56,7 +56,7 @@
v-hasPermi=
"['apihub:user-api-usage:delete']"
>
<Icon
icon=
"ep:delete"
class=
"mr-5px"
/>
批量删除
</el-button>
</el-button>
-->
</el-form-item>
</el-form>
</ContentWrap>
...
...
@@ -72,15 +72,15 @@
@
selection-change=
"handleRowCheckboxChange"
>
<el-table-column
type=
"selection"
width=
"55"
/>
<el-table-column
label=
"用户手机号"
align=
"center"
prop=
"userMobile"
width=
"150px"
/>
<el-table-column
label=
"用户手机号"
align=
"center"
prop=
"userMobile"
width=
"150px"
/>
<el-table-column
label=
"用户昵称"
align=
"center"
prop=
"userNickname"
width=
"150px"
/>
<el-table-column
label=
"api名称"
align=
"center"
prop=
"apiName"
width=
"150px"
/>
<el-table-column
label=
"套餐名称"
align=
"center"
prop=
"packageName"
width=
"150px"
/>
<el-table-column
label=
"套餐总量"
align=
"center"
prop=
"packageTimes"
/>
<el-table-column
label=
"有效时长"
align=
"center"
prop=
"packageValidDays"
>
<template
#
default=
"scope"
>
{{
scope
.
row
.
packageValidDays
}}
天
</
template
>
</el-table-column>
<el-table-column
label=
"已使用次数"
align=
"center"
prop=
"usedTimes"
width=
"150px"
/>
<template
#
default=
"scope"
>
{{
scope
.
row
.
packageValidDays
}}
天
</
template
>
</el-table-column>
<el-table-column
label=
"已使用次数"
align=
"center"
prop=
"usedTimes"
width=
"150px"
/>
<el-table-column
label=
"过期时间"
align=
"center"
...
...
@@ -95,9 +95,10 @@
:formatter=
"dateFormatter"
width=
"180px"
/>
<el-table-column
label=
"操作"
align=
"center"
min-width=
"1
2
0px"
>
<el-table-column
label=
"操作"
align=
"center"
min-width=
"1
8
0px"
>
<
template
#
default=
"scope"
>
<el-button
<el-button
link
type=
"primary"
@
click=
"handleDetail(scope.row.id)"
>
详情
</el-button>
<!--
<el-button
link
type=
"primary"
@
click=
"openForm('update', scope.row.id)"
...
...
@@ -112,7 +113,7 @@
v-hasPermi=
"['apihub:user-api-usage:delete']"
>
删除
</el-button>
</el-button>
-->
</
template
>
</el-table-column>
</el-table>
...
...
@@ -125,6 +126,9 @@
/>
</ContentWrap>
<!-- 详情弹窗 -->
<UserApiUsageDetail
ref=
"detailRef"
/>
<!-- 表单弹窗:添加/修改 -->
<UserApiUsageForm
ref=
"formRef"
@
success=
"getList"
/>
</template>
...
...
@@ -135,6 +139,7 @@ import { dateFormatter } from '@/utils/formatTime'
import
download
from
'@/utils/download'
import
{
UserApiUsageApi
,
UserApiUsage
}
from
'@/api/apihub/userapiusage'
import
UserApiUsageForm
from
'./UserApiUsageForm.vue'
import
UserApiUsageDetail
from
'./UserApiUsageDetail.vue'
/** 用户API管理 列表 */
defineOptions
({
name
:
'UserApiUsage'
})
...
...
@@ -185,6 +190,12 @@ const openForm = (type: string, id?: number) => {
formRef
.
value
.
open
(
type
,
id
)
}
/** 详情操作 */
const
detailRef
=
ref
()
const
handleDetail
=
(
id
:
number
)
=>
{
detailRef
.
value
.
open
(
id
)
}
/** 删除按钮操作 */
const
handleDelete
=
async
(
id
:
number
)
=>
{
try
{
...
...
@@ -203,15 +214,15 @@ const handleDeleteBatch = async () => {
try
{
// 删除的二次确认
await
message
.
delConfirm
()
await
UserApiUsageApi
.
deleteUserApiUsageList
(
checkedIds
.
value
)
;
await
UserApiUsageApi
.
deleteUserApiUsageList
(
checkedIds
.
value
)
message
.
success
(
t
(
'common.delSuccess'
))
await
getList
()
;
await
getList
()
}
catch
{}
}
const
checkedIds
=
ref
<
number
[]
>
([])
const
handleRowCheckboxChange
=
(
records
:
UserApiUsage
[])
=>
{
checkedIds
.
value
=
records
.
map
((
item
)
=>
item
.
id
)
;
checkedIds
.
value
=
records
.
map
((
item
)
=>
item
.
id
)
}
/** 导出按钮操作 */
...
...
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