Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
saas-manage
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
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
chehuidong
saas-manage
Commits
d189add5
Commit
d189add5
authored
Jun 07, 2025
by
wusiyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 新增客户管理-客户余额管理页面
parent
75ad97ed
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
560 additions
and
9 deletions
+560
-9
src/common/api/user/user.js
+20
-0
src/common/components/element-ui.js
+11
-9
src/router/index.js
+6
-0
src/views/home/navMenu.vue
+8
-0
src/views/user/balance.vue
+515
-0
No files found.
src/common/api/user/user.js
View file @
d189add5
...
...
@@ -6,3 +6,23 @@ export function getUserRechargeRecordListApi(params) {
export
function
getSubjectListApi
(
params
)
{
return
axios
.
get
(
'/pay/businessPayRecord/subjectList'
,
params
)
}
// 客户余额管理 列表
export
function
getCostomerBalanceApi
(
params
)
{
return
axios
.
post
(
'/business/customerBalance/list_page'
,
params
)
}
// 客户余额管理 编辑提交
export
function
editCustomerBalanceApi
(
params
)
{
return
axios
.
post
(
'/business/customerBalance/update'
,
params
)
}
// 客户余额管理 手动充值
export
function
customerBalanceRechargeApi
(
params
)
{
return
axios
.
post
(
'/business/customerBalance/recharge'
,
params
)
}
// 客户余额管理 批量删除
export
function
customerBalanceDelete
(
params
)
{
return
axios
.
post
(
'/business/customerBalance/delete?ids='
+
params
)
}
// 获取操作日志
// export function getLogApi(params) {
// return axios.get('/pay/businessPayRecord/subjectList', params)
// }
src/common/components/element-ui.js
View file @
d189add5
...
...
@@ -38,7 +38,8 @@ import {
CheckboxGroup
,
Divider
,
Popover
,
Upload
Upload
,
Link
}
from
'element-ui'
const
components
=
[
...
...
@@ -76,7 +77,8 @@ const components = [
ColorPicker
,
CheckboxGroup
,
Popover
,
Upload
Upload
,
Link
]
export
default
{
...
...
@@ -88,13 +90,13 @@ export default {
Vue
.
prototype
.
$message
=
(
message
)
=>
typeof
message
===
'string'
?
Message
({
duration
:
2500
,
message
,
})
duration
:
2500
,
message
})
:
Message
({
duration
:
2500
,
...
message
,
})
duration
:
2500
,
...
message
})
Vue
.
prototype
.
$message
.
success
=
(
message
)
=>
typeof
message
===
'string'
?
Message
.
success
({
duration
:
2500
,
message
})
...
...
@@ -115,5 +117,5 @@ export default {
Vue
.
prototype
.
$alert
=
MessageBox
.
alert
Vue
.
prototype
.
$confirm
=
MessageBox
.
confirm
Vue
.
prototype
.
$prompt
=
MessageBox
.
prompt
}
,
}
}
src/router/index.js
View file @
d189add5
...
...
@@ -103,6 +103,12 @@ const routes = [
meta
:
{
title
:
'充值记录'
}
},
{
path
:
'/saas/user/balance'
,
component
:
()
=>
import
(
'@/views/user/balance.vue'
),
name
:
'user_balance'
,
meta
:
{
title
:
'客户余额管理'
}
},
{
path
:
'/saas/logistics/transporters'
,
component
:
()
=>
import
(
'@/views/system/transporters.vue'
),
name
:
'system_transporters'
,
...
...
src/views/home/navMenu.vue
View file @
d189add5
...
...
@@ -423,6 +423,14 @@ export default {
icon
:
'el-icon-user'
,
index
:
'/saas/user/recharge-record'
,
children
:
[]
},
{
id
:
3
,
path
:
''
,
label
:
'客户余额管理'
,
icon
:
'el-icon-money'
,
index
:
'/saas/user/balance'
,
children
:
[]
}
]
},
...
...
src/views/user/balance.vue
0 → 100644
View file @
d189add5
<
template
>
<div
class=
"wraper"
>
<div
class=
"search"
>
<el-form
:model=
"searchForm"
size=
"small"
:inline=
"true"
>
<el-form-item
label=
"域名"
>
<el-input
v-model=
"searchForm.domain"
placeholder=
"请输入域名"
clearable
></el-input>
</el-form-item>
<el-form-item
label=
"客户名称"
>
<el-input
v-model=
"searchForm.companyName"
placeholder=
"请输入客户名称"
clearable
></el-input>
</el-form-item>
<el-form-item
label=
"客户编码"
>
<el-input
v-model=
"searchForm.userMark"
placeholder=
"请输入客户编码"
clearable
></el-input>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
size=
"small"
icon=
"el-icon-search"
@
click=
"search"
>
查询
</el-button>
</el-form-item>
<el-form-item>
<el-button
type=
"danger"
size=
"small"
icon=
"el-icon-delete"
@
click=
"deleteSection"
>
删除
</el-button>
</el-form-item>
</el-form>
</div>
<div
class=
"table"
v-loading=
"loading"
>
<el-table
ref=
"table"
:data=
"balanceList"
border
height=
"100%"
width=
"100%"
:highlight-current-row=
"true"
@
selection-change=
"handleSelectionChange"
header-row-class-name=
"header-row-class-name"
>
<el-table-column
type=
"selection"
width=
"55"
header-align=
"center"
align=
"center"
></el-table-column>
<el-table-column
label=
"序号"
type=
"index"
width=
"50"
align=
"center"
fixed=
"left"
></el-table-column>
<el-table-column
label=
"域名"
prop=
"domain"
header-align=
"center"
min-width=
"300"
:show-overflow-tooltip=
"true"
>
<template
slot-scope=
"scope"
>
<el-link
:href=
"'https://' + scope.row.domain"
target=
"_blank"
type=
"primary"
>
{{
scope
.
row
.
domain
}}
</el-link>
</
template
>
</el-table-column>
<el-table-column
label=
"公司名称"
prop=
"companyName"
align=
"center"
width=
"200"
:show-overflow-tooltip=
"true"
></el-table-column>
<el-table-column
label=
"客户编码"
prop=
"userMark"
align=
"center"
width=
"150"
:show-overflow-tooltip=
"true"
></el-table-column>
<el-table-column
label=
"折扣(%)"
prop=
"discountRate"
align=
"center"
width=
"150"
:show-overflow-tooltip=
"true"
></el-table-column>
<el-table-column
label=
"授信额度(元)"
prop=
"lineCredit"
align=
"center"
width=
"150"
:show-overflow-tooltip=
"true"
></el-table-column>
<el-table-column
label=
"余额(元)"
prop=
"balance"
align=
"center"
width=
"150"
:show-overflow-tooltip=
"true"
></el-table-column>
<el-table-column
label=
"消费金额(元)"
prop=
"usedQuota"
align=
"center"
width=
"150"
:show-overflow-tooltip=
"true"
></el-table-column>
<el-table-column
label=
"创建时间"
prop=
"createTime"
align=
"center"
width=
"200"
:show-overflow-tooltip=
"true"
></el-table-column>
<el-table-column
label=
"更新时间"
prop=
"updateTime"
align=
"center"
width=
"200"
:show-overflow-tooltip=
"true"
></el-table-column>
<el-table-column
label=
"操作"
align=
"center"
header-align=
"center"
width=
"80"
fixed=
"right"
>
<
template
slot-scope=
"scope"
>
<div
style=
"
display: flex;
align-items: center;
justify-content: space-around;
font-size: 20px;
"
>
<i
class=
"el-icon-edit"
style=
"cursor: pointer; color: #e6a23c"
title=
"编辑"
@
click=
"handleEdit(scope.row)"
></i>
<i
class=
"el-icon-coin"
title=
"手动充值"
@
click=
"handleRecharge(scope.row)"
style=
"cursor: pointer; color: #67c23a"
></i>
<!--
<i
class=
"el-icon-document"
title=
"操作日志"
@
click=
"handleLog(scope.row)"
style=
"cursor: pointer; color: #1565c0"
></i>
-->
</div>
</
template
>
</el-table-column>
</el-table>
</div>
<div
class=
"pagination"
>
<el-pagination
layout=
"sizes, total, prev, pager, next, jumper"
background
:total=
"total"
:page-size=
"pageSize"
:current-page=
"currentPage"
@
size-change=
"sizeChange"
@
current-change=
"onCurrentChange"
></el-pagination>
</div>
<!-- 编辑 弹窗 -->
<el-dialog
:title=
"'编辑'"
:visible
.
sync=
"editVisible"
width=
"700px"
@
submit
.
native
.
prevent
:close-on-click-modal=
"false"
>
<el-form
:model=
"editForm"
size=
"small"
ref=
"editForm"
label-width=
"150px"
label-position=
"right"
>
<el-form-item
label=
"折扣(%)"
type=
"number"
prop=
"discountRate"
:rules=
"[{ validator: validateDiscount, trigger: 'blur' }]"
>
<el-input
type=
"number"
min=
"0"
max=
"100"
v-model=
"editForm.discountRate"
size=
"small"
placeholder=
"请输入折扣"
/>
</el-form-item>
<el-form-item
label=
"授信额度(元)"
type=
"number"
prop=
"lineCredit"
:rules=
"[{ validator: validateBalance, trigger: 'blur' }]"
>
<el-input
type=
"number"
min=
"0"
v-model=
"editForm.lineCredit"
size=
"small"
placeholder=
"请输入授信额度"
/>
</el-form-item>
<el-form-item
label=
"余额(元)"
prop=
"balance"
>
<el-input
v-model=
"editForm.balance"
size=
"small"
:disabled=
"true"
style=
"cursor: not-allow"
/>
</el-form-item>
<el-form-item
label=
"消费金额(元)"
prop=
"consumptionAmount"
>
<el-input
v-model=
"editForm.consumptionAmount"
size=
"small"
:disabled=
"true"
/>
</el-form-item>
</el-form>
<span
slot=
"footer"
>
<el-button
@
click=
"editVisible = false"
size=
"small"
>
取消
</el-button>
<el-button
@
click=
"editSave"
type=
"primary"
size=
"small"
>
保存
</el-button>
</span>
</el-dialog>
<!-- 手动充值 弹窗 -->
<el-dialog
:title=
"'手动充值'"
:visible
.
sync=
"rechargeVisible"
:close-on-click-modal=
"false"
@
submit
.
native
.
prevent
width=
"700px"
>
<el-form
:model=
"rechargeForm"
size=
"small"
ref=
"rechargeForm"
label-width=
"150px"
label-position=
"right"
>
<el-form-item
label=
"充值金额(元)"
prop=
"balance"
:rules=
"[
{
required: true,
message: '请输入充值金额(元)',
trigger: 'blur'
},
{ validator: validateBalance, trigger: 'blur' }
]"
>
<el-input
type=
"number"
min=
"0"
v-model=
"rechargeForm.balance"
size=
"small"
placeholder=
"请输入充值金额(元)"
/>
</el-form-item>
</el-form>
<span
slot=
"footer"
>
<el-button
@
click=
"rechargeVisible = false"
size=
"small"
>
取消
</el-button>
<el-button
@
click=
"rechargeSave"
type=
"primary"
size=
"small"
>
保存
</el-button>
</span>
</el-dialog>
<!-- 操作日志 -->
<!-- <el-dialog :title="'操作日志'" :visible.sync="logVisible" width="700px">
<ul style="color: #333; font-size: 12px; height: 600px; overflow: auto">
<li v-for="(item, index) in logList" :key="index">
{{ item.createTime + ' ' + item.description }}
</li>
</ul>
</el-dialog> -->
</div>
</template>
<
script
>
import
{
getCostomerBalanceApi
,
editCustomerBalanceApi
,
customerBalanceRechargeApi
,
customerBalanceDelete
}
from
'@/common/api/user/user'
export
default
{
name
:
'userBalance'
,
data
()
{
return
{
searchForm
:
{},
rechargeForm
:
{},
editForm
:
{},
balanceList
:
[],
// logList: [],
selection
:
[],
loading
:
false
,
total
:
0
,
currentPage
:
1
,
pageSize
:
50
,
editVisible
:
false
,
rechargeVisible
:
false
// logVisible: false
}
},
created
()
{
this
.
getList
()
},
methods
:
{
// 查询
search
()
{
this
.
currentPage
=
1
this
.
getList
()
},
onCurrentChange
(
currentPage
)
{
this
.
currentPage
=
currentPage
this
.
getList
()
},
sizeChange
(
pageSize
)
{
this
.
pageSize
=
pageSize
this
.
currentPage
=
1
this
.
getList
()
},
handleSelectionChange
(
selection
)
{
this
.
selection
=
selection
},
// 获取列表数据
async
getList
()
{
this
.
loading
=
true
try
{
const
res
=
await
getCostomerBalanceApi
({
...
this
.
searchForm
,
currentPage
:
this
.
currentPage
,
pageSize
:
this
.
pageSize
})
this
.
balanceList
=
res
.
data
.
records
this
.
total
=
res
.
data
.
total
}
catch
(
e
)
{
console
.
error
(
e
)
}
finally
{
this
.
loading
=
false
}
},
// 编辑
async
handleEdit
(
row
)
{
this
.
editForm
=
row
this
.
editVisible
=
true
},
// 编辑提交
async
editSave
()
{
this
.
$refs
.
editForm
.
validate
(
async
(
valid
)
=>
{
if
(
!
valid
)
{
return
}
try
{
await
editCustomerBalanceApi
({
...
this
.
editForm
})
}
catch
(
e
)
{
console
.
log
(
e
)
}
finally
{
this
.
editVisible
=
false
this
.
currentPage
=
1
this
.
editForm
=
{}
await
this
.
getList
()
}
})
},
// 手动充值弹窗
async
handleRecharge
(
row
)
{
this
.
rechargeForm
=
{}
this
.
rechargeForm
.
id
=
row
.
id
this
.
rechargeVisible
=
true
},
// 手动充值提交
async
rechargeSave
()
{
this
.
$refs
.
rechargeForm
.
validate
(
async
(
valid
)
=>
{
if
(
!
valid
)
{
return
}
try
{
await
customerBalanceRechargeApi
({
...
this
.
rechargeForm
})
}
catch
(
e
)
{
console
.
log
(
e
)
}
finally
{
this
.
rechargeVisible
=
false
this
.
rechargeForm
=
{}
this
.
currentPage
=
1
await
this
.
getList
()
}
})
},
// 批量删除
async
deleteSection
(
v
)
{
if
(
this
.
selection
.
length
===
0
)
{
this
.
$message
.
error
(
'请至少选择一条记录'
)
return
}
let
ids
=
[]
ids
=
this
.
selection
.
map
((
item
)
=>
item
.
id
)
ids
=
ids
.
join
()
const
warning
=
this
.
$loading
({
background
:
'rgba(0, 0, 0, 0.3)'
})
try
{
await
customerBalanceDelete
(
ids
)
}
catch
(
e
)
{
console
.
error
(
e
)
}
finally
{
warning
.
close
()
this
.
currentPage
=
1
this
.
getList
()
}
},
// 金额校验
validateBalance
(
rule
,
value
,
callback
)
{
if
(
value
===
''
||
value
===
null
||
value
===
undefined
)
{
callback
()
}
else
if
(
Number
(
value
)
<
0
)
{
callback
(
new
Error
(
'值不能小于0'
))
}
else
{
callback
()
}
},
// 折扣校验
validateDiscount
(
rule
,
value
,
callback
)
{
if
(
value
===
''
||
value
===
null
||
value
===
undefined
)
{
callback
()
}
else
if
(
Number
(
value
)
<
0
||
Number
(
value
)
>
100
)
{
callback
(
new
Error
(
'值需要介于0到100之间'
))
}
else
{
callback
()
}
}
// 查看操作日志
// async handleLog(row) {
// try {
// this.logList = await getLogApi({ ...row })
// } catch (e) {
// console.log(e)
// } finally {
// this.logVisible = true
// }
// }
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.wraper
{
height
:
100%
;
overflow
:
hidden
;
background
:
#fff
;
border-radius
:
5px
;
padding
:
10px
;
display
:
flex
;
flex-direction
:
column
;
&::v-deep
{
.el-table
.el-table__cell
{
padding
:
6px
0
;
}
.el-input__inner
{
padding
:
0
4px
;
}
.el-input--small
.el-input__inner
{
height
:
30px
;
line-height
:
30px
;
}
.el-icon-time
:before
{
content
:
''
;
}
.el-dialog__footer
{
text-align
:
center
;
.el-button--small
{
padding
:
9px
50px
;
}
}
.el-dialog__body
{
padding
:
10px
20px
;
}
.el-icon-edit
:before
{
color
:
#ff9800
;
font-weight
:
bold
;
}
.el-range-editor--small
.el-range-separator
{
line-height
:
31px
;
}
.header-row-class-name
th
{
background-color
:
#f8f8f9
;
}
.el-input-group__append
{
padding-left
:
0
;
}
}
}
.table
{
flex
:
1
;
overflow
:
hidden
;
}
</
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