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
Unverified
Commit
d096e6e7
authored
Aug 22, 2023
by
芋道源码
Committed by
Gitee
Aug 22, 2023
Browse files
Options
Browse Files
Download
Plain Diff
!212 管理后台 用户详情
Merge pull request !212 from 风狗/用户详情
parents
5baccbd5
c1a40e7c
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
658 additions
and
1 deletions
+658
-1
src/api/member/point/record/index.ts
+8
-0
src/api/member/signin/record/index.ts
+9
-0
src/api/member/user/index.ts
+17
-1
src/views/member/user/components/account-info.vue
+43
-0
src/views/member/user/components/address-list.vue
+13
-0
src/views/member/user/components/balance-list.vue
+13
-0
src/views/member/user/components/card-title.vue
+36
-0
src/views/member/user/components/growth-list.vue
+13
-0
src/views/member/user/components/point-list.vue
+153
-0
src/views/member/user/components/sign-list.vue
+136
-0
src/views/member/user/detail/index.vue
+217
-0
No files found.
src/api/member/point/record/index.ts
View file @
d096e6e7
...
@@ -14,6 +14,14 @@ export interface RecordVO {
...
@@ -14,6 +14,14 @@ export interface RecordVO {
thawingTime
:
Date
thawingTime
:
Date
createDate
:
Date
createDate
:
Date
}
}
export
interface
RecordQueryVO
{
bizType
:
string
|
null
|
undefined
title
:
string
|
null
|
undefined
pageNo
:
number
pageSize
:
number
userId
:
number
|
null
|
undefined
createDate
:
string
[]
}
// 查询用户积分记录列表
// 查询用户积分记录列表
export
const
getRecordPage
=
async
(
params
)
=>
{
export
const
getRecordPage
=
async
(
params
)
=>
{
...
...
src/api/member/signin/record/index.ts
View file @
d096e6e7
...
@@ -6,6 +6,15 @@ export interface SignInRecordVO {
...
@@ -6,6 +6,15 @@ export interface SignInRecordVO {
day
:
number
day
:
number
point
:
number
point
:
number
}
}
export
interface
SignInRecordQueryVO
{
pageNo
:
number
pageSize
:
number
userId
?:
number
nickname
:
number
|
undefined
|
null
day
?:
number
|
null
|
undefined
point
?:
number
|
null
|
undefined
createTime
:
string
[]
|
null
|
undefined
}
// 查询用户签到积分列表
// 查询用户签到积分列表
export
const
getSignInRecordPage
=
async
(
params
)
=>
{
export
const
getSignInRecordPage
=
async
(
params
)
=>
{
...
...
src/api/member/user/index.ts
View file @
d096e6e7
...
@@ -17,7 +17,23 @@ export interface UserVO {
...
@@ -17,7 +17,23 @@ export interface UserVO {
mark
:
string
mark
:
string
createTime
:
Date
createTime
:
Date
}
}
export
interface
UserBaseInfoVO
{
id
:
number
|
undefined
|
null
mobile
:
string
password
:
string
|
null
|
undefined
status
:
number
registerIp
:
string
|
null
|
undefined
loginIp
:
string
|
null
|
undefined
loginDate
:
Date
|
null
|
undefined
nickname
:
string
|
null
|
undefined
avatar
:
string
|
null
|
undefined
name
:
string
|
null
|
undefined
sex
:
number
areaId
:
number
|
null
|
undefined
birthday
:
Date
|
null
|
undefined
mark
:
string
|
null
|
undefined
createTime
:
Date
|
null
|
undefined
}
// 查询会员用户列表
// 查询会员用户列表
export
const
getUserPage
=
async
(
params
)
=>
{
export
const
getUserPage
=
async
(
params
)
=>
{
return
await
request
.
get
({
url
:
`/member/user/page`
,
params
})
return
await
request
.
get
({
url
:
`/member/user/page`
,
params
})
...
...
src/views/member/user/components/account-info.vue
0 → 100644
View file @
d096e6e7
<
template
>
<el-descriptions
:column=
"2"
>
<el-descriptions-item>
<template
#
label
>
<div
class=
"cell-item"
>
储值余额
</div>
</
template
>
{{ 0 }}
</el-descriptions-item>
<el-descriptions-item>
<
template
#
label
>
<div
class=
"cell-item"
>
现金余额
</div>
</
template
>
{{ 0 }}
</el-descriptions-item>
<el-descriptions-item>
<
template
#
label
>
<div
class=
"cell-item"
>
积分
</div>
</
template
>
{{ 0 }}
</el-descriptions-item>
<el-descriptions-item>
<
template
#
label
>
<div
class=
"cell-item"
>
成长值
</div>
</
template
>
{{ 0 }}
</el-descriptions-item>
</el-descriptions>
</template>
<
script
lang=
"ts"
setup
>
import
{
defineComponent
}
from
'vue'
defineComponent
({
name
:
'AccountInfo'
})
</
script
>
<
style
scoped
lang=
"scss"
>
.cell-item
{
display
:
inline
;
}
.cell-item
::after
{
content
:
':'
;
}
</
style
>
src/views/member/user/components/address-list.vue
0 → 100644
View file @
d096e6e7
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'vue'
export
default
defineComponent
({
name
:
'AddressList'
})
</
script
>
<
template
>
<div>
收货地址列表
</div>
</
template
>
<
style
scoped
lang=
"scss"
></
style
>
src/views/member/user/components/balance-list.vue
0 → 100644
View file @
d096e6e7
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'vue'
export
default
defineComponent
({
name
:
'BalanceList'
})
</
script
>
<
template
>
<div>
余额列表
</div>
</
template
>
<
style
scoped
lang=
"scss"
></
style
>
src/views/member/user/components/card-title.vue
0 → 100644
View file @
d096e6e7
<
script
lang=
"ts"
setup
>
import
{
defineComponent
}
from
'vue'
defineComponent
({
name
:
'CardTitle'
})
const
{
title
}
=
defineProps
({
title
:
{
type
:
String
,
required
:
true
}
})
</
script
>
<
template
>
<span
class=
"card-title"
>
{{
title
}}
</span>
</
template
>
<
style
scoped
lang=
"scss"
>
.card-title
{
font-size
:
14px
;
font-weight
:
600
;
&::before
{
content
:
''
;
display
:
inline-block
;
width
:
3px
;
height
:
14px
;
//
background-color
:
#105cfb
;
background
:
var
(
--el-color-primary
);
position
:
relative
;
left
:
-5px
;
top
:
8px
;
border-radius
:
5px
;
transform
:
translateY
(
-50%
);
}
}
</
style
>
src/views/member/user/components/growth-list.vue
0 → 100644
View file @
d096e6e7
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'vue'
export
default
defineComponent
({
name
:
'GrowthList'
})
</
script
>
<
template
>
<div>
成长值列表
</div>
</
template
>
<
style
scoped
lang=
"scss"
></
style
>
src/views/member/user/components/point-list.vue
0 → 100644
View file @
d096e6e7
<
template
>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class=
"-mb-15px"
:model=
"queryParams"
ref=
"queryFormRef"
:inline=
"true"
label-width=
"68px"
>
<el-form-item
label=
"业务类型"
prop=
"bizType"
>
<el-select
v-model=
"queryParams.bizType"
placeholder=
"请选择业务类型"
clearable
class=
"!w-240px"
>
<el-option
v-for=
"dict in getIntDictOptions(DICT_TYPE.MEMBER_POINT_BIZ_TYPE)"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"积分标题"
prop=
"title"
>
<el-input
v-model=
"queryParams.title"
placeholder=
"请输入积分标题"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"获得时间"
prop=
"createDate"
>
<el-date-picker
v-model=
"queryParams.createDate"
value-format=
"YYYY-MM-DD HH:mm:ss"
type=
"daterange"
start-placeholder=
"开始日期"
end-placeholder=
"结束日期"
:default-time=
"[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item>
<el-button
@
click=
"handleQuery"
>
<Icon
icon=
"ep:search"
class=
"mr-5px"
/>
搜索
</el-button>
<el-button
@
click=
"resetQuery"
>
<Icon
icon=
"ep:refresh"
class=
"mr-5px"
/>
重置
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table
v-loading=
"loading"
:data=
"list"
>
<el-table-column
label=
"编号"
align=
"center"
prop=
"id"
width=
"180"
/>
<el-table-column
label=
"获得时间"
align=
"center"
prop=
"createTime"
:formatter=
"dateFormatter"
width=
"180"
/>
<el-table-column
label=
"用户"
align=
"center"
prop=
"nickname"
width=
"200"
/>
<el-table-column
label=
"获得积分"
align=
"center"
prop=
"point"
width=
"100"
>
<template
#
default=
"scope"
>
<el-tag
v-if=
"scope.row.point > 0"
class=
"ml-2"
type=
"success"
effect=
"dark"
>
+
{{
scope
.
row
.
point
}}
</el-tag>
<el-tag
v-else
class=
"ml-2"
type=
"danger"
effect=
"dark"
>
{{
scope
.
row
.
point
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
label=
"总积分"
align=
"center"
prop=
"totalPoint"
width=
"100"
/>
<el-table-column
label=
"标题"
align=
"center"
prop=
"title"
/>
<el-table-column
label=
"描述"
align=
"center"
prop=
"description"
/>
<el-table-column
label=
"业务编码"
align=
"center"
prop=
"bizId"
/>
<el-table-column
label=
"业务类型"
align=
"center"
prop=
"bizType"
>
<
template
#
default=
"scope"
>
<dict-tag
:type=
"DICT_TYPE.MEMBER_POINT_BIZ_TYPE"
:value=
"scope.row.bizType"
/>
</
template
>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total=
"total"
v-model:page=
"queryParams.pageNo"
v-model:limit=
"queryParams.pageSize"
@
pagination=
"getList"
/>
</ContentWrap>
</template>
<
script
lang=
"ts"
setup
>
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
import
{
dateFormatter
}
from
'@/utils/formatTime'
import
*
as
RecordApi
from
'@/api//member/point/record'
import
{
RecordQueryVO
}
from
'@/api//member/point/record'
defineOptions
({
name
:
'PointList'
})
const
loading
=
ref
(
true
)
// 列表的加载中
const
total
=
ref
(
0
)
// 列表的总页数
const
list
=
ref
([])
// 列表的数据
const
queryParams
=
reactive
<
RecordQueryVO
>
({
pageNo
:
1
,
pageSize
:
10
,
bizType
:
undefined
,
title
:
null
,
createDate
:
[],
userId
:
null
})
const
queryFormRef
=
ref
()
// 搜索的表单
/** 查询列表 */
const
getList
=
async
()
=>
{
loading
.
value
=
true
try
{
const
data
=
await
RecordApi
.
getRecordPage
(
queryParams
)
list
.
value
=
data
.
list
total
.
value
=
data
.
total
}
finally
{
loading
.
value
=
false
}
}
/** 搜索按钮操作 */
const
handleQuery
=
()
=>
{
queryParams
.
pageNo
=
1
getList
()
}
/** 重置按钮操作 */
const
resetQuery
=
()
=>
{
queryFormRef
.
value
.
resetFields
()
handleQuery
()
}
const
{
memberId
}
=
defineProps
({
memberId
:
{
type
:
Number
,
required
:
true
}
})
/** 初始化 **/
onMounted
(()
=>
{
queryParams
.
userId
=
memberId
getList
()
})
</
script
>
src/views/member/user/components/sign-list.vue
0 → 100644
View file @
d096e6e7
<
template
>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class=
"-mb-15px"
:model=
"queryParams"
ref=
"queryFormRef"
:inline=
"true"
label-width=
"68px"
>
<el-form-item
label=
"签到用户"
prop=
"nickname"
>
<el-input
v-model=
"queryParams.nickname"
placeholder=
"请输入签到用户"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"签到天数"
prop=
"day"
>
<el-input
v-model=
"queryParams.day"
placeholder=
"请输入签到天数"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"签到时间"
prop=
"createTime"
>
<el-date-picker
v-model=
"queryParams.createTime"
value-format=
"YYYY-MM-DD HH:mm:ss"
type=
"daterange"
start-placeholder=
"开始日期"
end-placeholder=
"结束日期"
:default-time=
"[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item>
<el-button
@
click=
"handleQuery"
><Icon
icon=
"ep:search"
class=
"mr-5px"
/>
搜索
</el-button>
<el-button
@
click=
"resetQuery"
><Icon
icon=
"ep:refresh"
class=
"mr-5px"
/>
重置
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table
v-loading=
"loading"
:data=
"list"
>
<el-table-column
label=
"编号"
align=
"center"
prop=
"id"
/>
<el-table-column
label=
"签到用户"
align=
"center"
prop=
"nickname"
/>
<el-table-column
label=
"签到天数"
align=
"center"
prop=
"day"
:formatter=
"(_, __, cellValue) => ['第', cellValue, '天'].join(' ')"
/>
<el-table-column
label=
"获得积分"
align=
"center"
prop=
"point"
width=
"100"
>
<template
#
default=
"scope"
>
<el-tag
v-if=
"scope.row.point > 0"
class=
"ml-2"
type=
"success"
effect=
"dark"
>
+
{{
scope
.
row
.
point
}}
</el-tag>
<el-tag
v-else
class=
"ml-2"
type=
"danger"
effect=
"dark"
>
{{
scope
.
row
.
point
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
label=
"签到时间"
align=
"center"
prop=
"createTime"
:formatter=
"dateFormatter"
/>
</el-table>
<!-- 分页 -->
<Pagination
:total=
"total"
v-model:page=
"queryParams.pageNo"
v-model:limit=
"queryParams.pageSize"
@
pagination=
"getList"
/>
</ContentWrap>
</template>
<
script
lang=
"ts"
setup
>
import
{
dateFormatter
}
from
'@/utils/formatTime'
import
*
as
SignInRecordApi
from
'@/api/member/signin/record'
import
{
SignInRecordQueryVO
}
from
'@/api/member/signin/record'
defineOptions
({
name
:
'SignList'
})
const
loading
=
ref
(
true
)
// 列表的加载中
const
total
=
ref
(
0
)
// 列表的总页数
const
list
=
ref
([])
// 列表的数据
const
queryParams
=
reactive
<
SignInRecordQueryVO
>
({
pageNo
:
1
,
pageSize
:
10
,
nickname
:
null
,
day
:
null
,
createTime
:
[]
})
const
queryFormRef
=
ref
()
// 搜索的表单
/** 查询列表 */
const
getList
=
async
()
=>
{
loading
.
value
=
true
try
{
const
data
=
await
SignInRecordApi
.
getSignInRecordPage
(
queryParams
)
list
.
value
=
data
.
list
total
.
value
=
data
.
total
}
finally
{
loading
.
value
=
false
}
}
/** 搜索按钮操作 */
const
handleQuery
=
()
=>
{
queryParams
.
pageNo
=
1
getList
()
}
/** 重置按钮操作 */
const
resetQuery
=
()
=>
{
queryFormRef
.
value
.
resetFields
()
handleQuery
()
}
const
{
memberId
}
=
defineProps
({
memberId
:
{
type
:
Number
,
required
:
true
}
})
/** 初始化 **/
onMounted
(()
=>
{
queryParams
.
userId
=
memberId
getList
()
})
</
script
>
src/views/member/user/detail/index.vue
0 → 100644
View file @
d096e6e7
<
template
>
<div
v-loading=
"loading"
>
<el-row
:gutter=
"10"
class=
"detail-info-warp"
>
<el-col
:span=
"14"
class=
"detail-info-item"
>
<el-card
shadow=
"never"
>
<template
#
header
>
<div
class=
"card-header"
>
<CardTitle
title=
"基本信息"
/>
<el-button
v-if=
"userInfo.id"
type=
"primary"
text
@
click=
"openForm('update', userInfo.id)"
>
编辑
</el-button
>
</div>
</
template
>
<el-row>
<el-col
:span=
"4"
>
<ElAvatar
shape=
"square"
:size=
"140"
:src=
"userInfo.avatar || undefined"
/>
</el-col>
<el-col
:span=
"20"
>
<el-descriptions
:column=
"2"
>
<el-descriptions-item>
<
template
#
label
>
<div
class=
"cell-item"
>
<Icon
icon=
"ep:user"
/>
用户名
</div>
</
template
>
{{ userInfo.name || '空' }}
</el-descriptions-item>
<el-descriptions-item>
<
template
#
label
>
<div
class=
"cell-item"
>
<Icon
icon=
"ep:user"
/>
昵称
</div>
</
template
>
{{ userInfo.nickname }}
</el-descriptions-item
>
<el-descriptions-item
label=
"手机号"
>
<
template
#
label
>
<div
class=
"cell-item"
>
<Icon
icon=
"ep:phone"
/>
手机号
</div>
</
template
>
{{ userInfo.mobile }}
</el-descriptions-item
>
<el-descriptions-item>
<
template
#
label
>
<div
class=
"cell-item"
>
<Icon
icon=
"fa:mars-double"
/>
性别
</div>
</
template
>
<dict-tag
:type=
"DICT_TYPE.SYSTEM_USER_SEX"
:value=
"userInfo.sex"
/>
</el-descriptions-item>
<el-descriptions-item>
<
template
#
label
>
<div
class=
"cell-item"
>
<Icon
icon=
"ep:location"
/>
所在地
</div>
</
template
>
{{ userInfo.areaId }}
</el-descriptions-item>
<el-descriptions-item>
<
template
#
label
>
<div
class=
"cell-item"
>
<Icon
icon=
"ep:position"
/>
注册IP
</div>
</
template
>
{{ userInfo.registerIp }}
</el-descriptions-item>
<el-descriptions-item>
<
template
#
label
>
<div
class=
"cell-item"
>
<Icon
icon=
"fa:birthday-cake"
/>
生日
</div>
</
template
>
{{ userInfo.birthday ? formatDate(userInfo.birthday) : '空' }}
</el-descriptions-item>
<el-descriptions-item>
<
template
#
label
>
<div
class=
"cell-item"
>
<Icon
icon=
"ep:calendar"
/>
注册时间
</div>
</
template
>
{{ userInfo.createTime ? formatDate(userInfo.createTime) : '空' }}
</el-descriptions-item>
<el-descriptions-item>
<
template
#
label
>
<div
class=
"cell-item"
>
<Icon
icon=
"ep:calendar"
/>
最后登录时间
</div>
</
template
>
{{ userInfo.loginDate ? formatDate(userInfo.loginDate) : '空' }}
</el-descriptions-item>
</el-descriptions>
</el-col>
</el-row>
</el-card>
</el-col>
<el-col
:span=
"10"
class=
"detail-info-item"
>
<el-card
shadow=
"never"
>
<
template
#
header
>
<CardTitle
title=
"账户信息(WIP)"
/>
</
template
>
<AccountInfo
/>
</el-card>
</el-col>
<el-card
header=
"账户明细"
style=
"width: 100%; margin-top: 20px"
shadow=
"never"
>
<
template
#
header
>
<CardTitle
title=
"账户明细"
/>
</
template
>
<el-tabs
v-model=
"activeName"
class=
"demo-tabs"
>
<el-tab-pane
label=
"积分"
name=
"point"
>
<PointList
v-if=
"userInfo.id"
:member-id=
"userInfo.id"
/>
</el-tab-pane>
<el-tab-pane
label=
"签到"
name=
"sign"
>
<SignList
v-if=
"userInfo.id"
:member-id=
"userInfo.id"
/>
</el-tab-pane>
<el-tab-pane
label=
"成长值"
name=
"third"
>
成长值(WIP)
</el-tab-pane>
<el-tab-pane
label=
"余额"
name=
"fourth"
>
余额(WIP)
</el-tab-pane>
</el-tabs>
</el-card>
</el-row>
</div>
<!-- 表单弹窗:添加/修改 -->
<UserForm
ref=
"formRef"
@
success=
"getUserData(userInfo.id)"
/>
</template>
<
script
setup
lang=
"ts"
>
import
{
ref
}
from
'vue'
import
PointList
from
'@/views/member/user/components/point-list.vue'
import
SignList
from
'@/views/member/user/components/sign-list.vue'
import
CardTitle
from
'@/views/member/user/components/card-title.vue'
import
{
ElMessage
}
from
'element-plus'
import
{
getUser
,
UserBaseInfoVO
}
from
'@/api/member/user'
import
{
formatDate
}
from
'@/utils/formatTime'
import
{
DICT_TYPE
}
from
'@/utils/dict'
import
UserForm
from
'@/views/member/user/UserForm.vue'
import
AccountInfo
from
'@/views/member/user/components/account-info.vue'
defineOptions
({
name
:
'MemberDetail'
})
const
activeName
=
ref
(
'point'
)
const
loading
=
ref
(
true
)
/** 添加/修改操作 */
const
formRef
=
ref
()
const
openForm
=
(
type
:
string
,
id
?:
number
)
=>
{
formRef
.
value
.
open
(
type
,
id
)
}
let
userInfo
=
ref
<
UserBaseInfoVO
>
({
areaId
:
undefined
,
avatar
:
undefined
,
birthday
:
undefined
,
createTime
:
undefined
,
id
:
undefined
,
loginDate
:
undefined
,
loginIp
:
''
,
mark
:
''
,
mobile
:
''
,
name
:
''
,
nickname
:
''
,
password
:
null
,
registerIp
:
undefined
,
sex
:
0
,
status
:
0
})
const
getUserData
=
async
(
id
:
any
)
=>
{
loading
.
value
=
true
try
{
// userInfo.value = Object.assign(userInfo, await getUser(parseInt(id as string)))
userInfo
.
value
=
await
getUser
(
parseInt
(
id
as
string
))
}
finally
{
loading
.
value
=
false
}
}
const
route
=
useRoute
()
let
router
=
useRouter
()
const
{
member_id
}
=
route
.
query
onMounted
(()
=>
{
if
(
!
member_id
)
{
ElMessage
.
warning
(
'会员id 未携带!'
)
router
.
back
()
return
}
getUserData
(
member_id
)
})
</
script
>
<
style
scoped
lang=
"css"
>
.detail-info-item
:first-child
{
padding-left
:
0
!important
;
}
/* first-child 不生效有没有大佬给看下q.q */
.detail-info-item
:nth-child
(
2
)
{
padding-right
:
0
!important
;
}
.card-header
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
}
.cell-item
{
display
:
inline
;
}
.cell-item
::after
{
content
:
':'
;
}
</
style
>
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