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
124f05e2
Commit
124f05e2
authored
Aug 19, 2026
by
zhuzhequan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:需求功能完善
parent
6b13a992
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
95 additions
and
275 deletions
+95
-275
src/common/api/offlineRecharge/index.js
+38
-0
src/common/api/paymentAccount/index.js
+0
-258
src/common/components/base/tableView.vue
+2
-2
src/views/user/jmManagement.vue
+50
-10
src/views/user/paymentAccountManageDialog.vue
+0
-0
src/views/user/rechargeRecord.vue
+5
-5
No files found.
src/common/api/offlineRecharge/index.js
0 → 100644
View file @
124f05e2
import
axios
from
'../axios'
/**
* 线下充值 - 请求方法(SAAS 端)
* 接口文档:@e:\zzq\saas-manage\图\jomalls-mange端账户相关接口.md
* 基础路径:/api/offline-recharge(需 token 校验)
*/
const
BASE
=
'/offline-recharge'
// ==================== 1. 左边栏状态统计 ====================
// POST /api/offline-recharge/status
// 响应:[ { code, remark, num } ]
export
function
getOfflineRechargeStatus
()
{
return
axios
.
post
(
`
${
BASE
}
/status`
)
}
// ==================== 2. 运营初审 ====================
// POST /api/offline-recharge/firstAudit
// 请求体 OfflineRechargeRecordParam:{ id, audit(boolean), rejectReason? }
export
function
firstAudit
(
data
)
{
return
axios
.
post
(
`
${
BASE
}
/firstAudit`
,
data
)
}
// ==================== 3. 财务复审 ====================
// POST /api/offline-recharge/secondAudit
// 请求体 OfflineRechargeRecordParam:{ id, audit(boolean), rejectReason?, actualAmount?, serviceFee?, financeBillUrl?, financeRemark? }
export
function
secondAudit
(
data
)
{
return
axios
.
post
(
`
${
BASE
}
/secondAudit`
,
data
)
}
// 状态码 -> 文案 映射
export
const
OFFLINE_RECHARGE_STATUS_MAP
=
{
OPER_APPROVED
:
'运营初审'
,
FIN_APPROVED
:
'财务复审'
,
SETTLED_AMOUNT
:
'充值成功'
,
WAIT_UPDATE
:
'充值失败'
}
src/common/api/paymentAccount/index.js
deleted
100644 → 0
View file @
6b13a992
import
axios
from
'../axios'
/**
* 付款账户管理 - 请求方法
* 说明:后端接口暂未联调,当前数据使用本地 mock;
* 联调时只需将函数体内的 mock 逻辑替换为真实 axios 请求即可(URL 已注释)。
*/
// ==================== mock 数据 ====================
let
paymentAccountList
=
[
{
id
:
1
,
accountName
:
'九猫科技团队CNY账户'
,
accountNo
:
'CNY260804001'
,
balance
:
12800.5
,
totalRecharge
:
20000
,
arrears
:
0
,
currency
:
'CNY'
,
creator
:
'张三'
,
createTime
:
'2026-08-04 10:20:33'
,
hasDetail
:
true
},
{
id
:
2
,
accountName
:
'一衣蔓蔓团队CNY账户'
,
accountNo
:
'CNY260804002'
,
balance
:
5632
,
totalRecharge
:
8000
,
arrears
:
0
,
currency
:
'CNY'
,
creator
:
'张三'
,
createTime
:
'2026-08-04 10:25:11'
,
hasDetail
:
false
},
{
id
:
3
,
accountName
:
'一本万利团队CNY账户'
,
accountNo
:
'CNY260804003'
,
balance
:
0
,
totalRecharge
:
5000
,
arrears
:
300
,
currency
:
'CNY'
,
creator
:
'李四'
,
createTime
:
'2026-08-04 10:30:45'
,
hasDetail
:
true
},
{
id
:
4
,
accountName
:
'九猫海外业务USD账户'
,
accountNo
:
'USD260804001'
,
balance
:
2200
,
totalRecharge
:
5000
,
arrears
:
0
,
currency
:
'USD'
,
creator
:
'李四'
,
createTime
:
'2026-08-05 09:12:08'
,
hasDetail
:
false
}
]
let
rechargeRecordList
=
[
{
id
:
1
,
accountId
:
1
,
rechargeNo
:
'CZ20260805001'
,
status
:
'充值成功'
,
payType
:
'支付宝扫码充值'
,
currency
:
'CNY'
,
amount
:
10000
,
serviceFee
:
0
,
actualAmount
:
10000
,
remark
:
'线下充值'
,
createTime
:
'2026-08-05 14:00:00'
},
{
id
:
2
,
accountId
:
1
,
rechargeNo
:
'CZ20260804002'
,
status
:
'充值中'
,
payType
:
'线下充值'
,
currency
:
'CNY'
,
amount
:
5000
,
serviceFee
:
0
,
actualAmount
:
5000
,
remark
:
'待审核'
,
createTime
:
'2026-08-04 18:30:00'
},
{
id
:
3
,
accountId
:
4
,
rechargeNo
:
'CZ20260805002'
,
status
:
'充值失败'
,
payType
:
'线下充值'
,
currency
:
'USD'
,
amount
:
3000
,
serviceFee
:
0
,
actualAmount
:
3000
,
remark
:
'水单不清晰'
,
createTime
:
'2026-08-05 16:00:00'
}
]
let
operationLogList
=
[
{
id
:
1
,
accountId
:
1
,
createTime
:
'2026-08-05 14:22:10'
,
description
:
'XXX审核充值单通过,充值单号为:CZ20260805001,入账金额为:10000¥'
},
{
id
:
2
,
accountId
:
1
,
createTime
:
'2026-08-04 15:40:55'
,
description
:
'XXX对账户九猫科技团队CNY账户进行手动调整,调整金额为:5000$,备注:测试调整;'
},
{
id
:
3
,
accountId
:
1
,
createTime
:
'2026-08-04 10:20:33'
,
description
:
'demo客户XXX添加了一个付款账户,账户名为:九猫科技团队CNY账户,账户币种为:CNY;'
}
]
// ==================== 工具 ====================
const
sleep
=
(
ms
=
300
)
=>
new
Promise
((
resolve
)
=>
setTimeout
(
resolve
,
ms
))
const
ok
=
(
data
,
message
=
'操作成功'
)
=>
({
code
:
200
,
data
,
message
})
// 生成账号:币种 + 年月日 + 三位数,如 CNY260805001
export
function
genAccountNo
(
currency
)
{
const
now
=
new
Date
()
const
ymd
=
`
${
now
.
getFullYear
()}
`
+
`
${
String
(
now
.
getMonth
()
+
1
).
padStart
(
2
,
'0'
)}
`
+
`
${
String
(
now
.
getDate
()).
padStart
(
2
,
'0'
)}
`
const
suffix
=
String
(
Math
.
floor
(
Math
.
random
()
*
900
)
+
100
)
return
`
${
currency
}${
ymd
}${
suffix
}
`
}
// ==================== 请求方法 ====================
// 分页查询付款账户列表
export
async
function
getPaymentAccountPage
(
params
)
{
await
sleep
()
let
list
=
[...
paymentAccountList
]
if
(
params
.
accountName
)
{
list
=
list
.
filter
((
item
)
=>
item
.
accountName
.
includes
(
params
.
accountName
))
}
if
(
params
.
accountNo
)
{
list
=
list
.
filter
((
item
)
=>
item
.
accountNo
.
includes
(
params
.
accountNo
))
}
if
(
params
.
currency
)
{
list
=
list
.
filter
((
item
)
=>
item
.
currency
===
params
.
currency
)
}
const
{
currentPage
=
1
,
pageSize
=
10
}
=
params
const
start
=
(
currentPage
-
1
)
*
pageSize
const
records
=
list
.
slice
(
start
,
start
+
pageSize
)
// 真实接口: axios.post('/customer/paymentAccount/pageList', params)
return
ok
({
records
,
total
:
list
.
length
})
}
// 新增付款账户
export
async
function
addPaymentAccount
(
params
)
{
await
sleep
()
paymentAccountList
.
unshift
({
id
:
Date
.
now
(),
...
params
,
balance
:
0
,
totalRecharge
:
0
,
arrears
:
0
,
creator
:
'当前用户'
,
createTime
:
'2026-08-06 09:00:00'
,
hasDetail
:
false
})
operationLogList
.
unshift
({
id
:
Date
.
now
()
+
1
,
accountId
:
paymentAccountList
[
0
].
id
,
createTime
:
'2026-08-06 09:00:00'
,
description
:
`demo客户XXX添加了一个付款账户,账户名为:
${
params
.
accountName
}
,账户币种为:
${
params
.
currency
}
;`
})
// 真实接口: axios.post('/customer/paymentAccount/add', params)
return
ok
(
null
,
'新增成功'
)
}
// 编辑付款账户
export
async
function
updatePaymentAccount
(
params
)
{
await
sleep
()
const
target
=
paymentAccountList
.
find
((
item
)
=>
item
.
id
===
params
.
id
)
if
(
target
)
{
target
.
accountName
=
params
.
accountName
}
// 真实接口: axios.post('/customer/paymentAccount/update', params)
return
ok
(
null
,
'编辑成功'
)
}
// 手动调整账户余额(amount 支持正负数)
export
async
function
adjustPaymentAccount
(
params
)
{
await
sleep
()
const
target
=
paymentAccountList
.
find
((
item
)
=>
item
.
id
===
params
.
id
)
if
(
target
)
{
target
.
balance
=
Number
((
target
.
balance
+
params
.
amount
).
toFixed
(
2
))
if
(
target
.
balance
<
0
)
{
target
.
arrears
=
Number
(
Math
.
abs
(
target
.
balance
).
toFixed
(
2
))
}
else
{
target
.
arrears
=
0
}
}
operationLogList
.
unshift
({
id
:
Date
.
now
(),
accountId
:
params
.
id
,
createTime
:
'2026-08-06 09:30:00'
,
description
:
`XXX对账户
${
params
.
accountName
}
进行手动调整,调整金额为:
${
params
.
amount
}
$,备注:
${
params
.
remark
||
'无'
}
;`
})
// 真实接口: axios.post('/customer/paymentAccount/adjust', params)
return
ok
(
null
,
'调整成功'
)
}
// 删除付款账户
export
async
function
deletePaymentAccount
(
params
)
{
await
sleep
()
const
target
=
paymentAccountList
.
find
((
item
)
=>
item
.
id
===
params
.
id
)
if
(
target
&&
target
.
hasDetail
)
{
return
{
code
:
500
,
message
:
`您要删除的账户
${
target
.
accountName
}
(
${
target
.
accountNo
}
)存在消费或充值明细,无法进行删除操作!`
,
data
:
null
}
}
paymentAccountList
=
paymentAccountList
.
filter
((
item
)
=>
item
.
id
!==
params
.
id
)
// 真实接口: axios.post('/customer/paymentAccount/delete', params)
return
ok
(
null
,
'删除成功'
)
}
// 分页查询充值记录
export
async
function
getRechargeRecordPage
(
params
)
{
await
sleep
()
let
list
=
rechargeRecordList
.
filter
((
item
)
=>
item
.
accountId
===
params
.
accountId
)
const
{
currentPage
=
1
,
pageSize
=
10
}
=
params
const
start
=
(
currentPage
-
1
)
*
pageSize
const
records
=
list
.
slice
(
start
,
start
+
pageSize
)
// 真实接口: axios.post('/customer/paymentAccount/rechargeRecord/pageList', params)
return
ok
({
records
,
total
:
list
.
length
})
}
// 分页查询操作日志
export
async
function
getOperationLogPage
(
params
)
{
await
sleep
()
let
list
=
operationLogList
.
filter
((
item
)
=>
item
.
accountId
===
params
.
accountId
)
.
sort
((
a
,
b
)
=>
(
a
.
createTime
<
b
.
createTime
?
1
:
-
1
))
const
{
currentPage
=
1
,
pageSize
=
10
}
=
params
const
start
=
(
currentPage
-
1
)
*
pageSize
const
records
=
list
.
slice
(
start
,
start
+
pageSize
)
// 真实接口: axios.post('/customer/paymentAccount/operationLog/pageList', params)
return
ok
({
records
,
total
:
list
.
length
})
}
src/common/components/base/tableView.vue
View file @
124f05e2
...
...
@@ -562,8 +562,8 @@ export default {
highlight
-
hover
-
row
show
-
header
=
{
this
.
showHeader
}
onCell
-
click
=
{
this
.
cellClick
}
show
-
header
-
overflow
show
-
overflow
show
-
header
-
overflow
=
"title"
show
-
overflow
=
"title"
height
=
"100%"
scroll
-
x
=
{{
gt
:
30
}}
scroll
-
y
=
{{
gt
:
30
,
enabled
:
this
.
virtualScroll
}}
...
...
src/views/user/jmManagement.vue
View file @
124f05e2
...
...
@@ -92,6 +92,10 @@
:commandTitle=
"commandTitle"
:erpStatus=
"erpStatus"
ref=
"customerRef"
/>
<paymentAccountManageDialog
:visible
.
sync=
"paymentAccountDialog"
:customer-id=
"paymentAccountRow.id"
:customer-name=
"paymentAccountRow.companyName || ''"
/>
<el-dialog
title=
"操作日志"
:close-on-click-modal=
"false"
...
...
@@ -160,6 +164,7 @@
import
tableView
from
'@/common/components/base/tableView.vue'
import
pagination
from
'../../mixins/pagination'
import
editCustmerDialog
from
'./editCustmerDialog.vue'
import
paymentAccountManageDialog
from
'./paymentAccountManageDialog.vue'
import
{
get
,
post
,
remove
}
from
'@/common/api/axios'
import
{
mapState
}
from
'vuex'
import
{
addGiftOrders
}
from
'@/common/api/manage/index'
...
...
@@ -168,7 +173,8 @@ export default {
mixins
:
[
pagination
],
components
:
{
tableView
,
editCustmerDialog
editCustmerDialog
,
paymentAccountManageDialog
},
data
()
{
return
{
...
...
@@ -186,6 +192,8 @@ export default {
logVisible
:
false
,
giftOrderVisible
:
false
,
logList
:
[],
paymentAccountDialog
:
false
,
paymentAccountRow
:
{},
searchForm
:
{
companyName
:
''
,
contactUserName
:
''
,
...
...
@@ -383,13 +391,22 @@ export default {
},
{
label
:
'订单账户'
,
key
:
'createTime'
,
width
:
130
key
:
'orderAccount'
,
width
:
130
,
align
:
'center'
,
render
:
(
row
)
=>
(
<
div
class
=
"order-account-cell"
>
<
span
class
=
"balance"
>
{
Number
(
row
.
orderBalance
||
0
)}
<
/span
>
<
span
class
=
"separator"
>
/ </
span
>
<
span
class
=
"recharge"
>
{
Number
(
row
.
orderAccumulatedRecharge
||
0
)}
<
/span
>
<
/div
>
)
},
{
label
:
'付款账户数量'
,
key
:
'createTime'
,
width
:
130
key
:
'paymentAccountCount'
,
width
:
120
,
align
:
'center'
},
{
label
:
'操作'
,
...
...
@@ -481,6 +498,13 @@ export default {
<
/el-button
>
<
/el-dropdown-item
>
)}
<
el
-
dropdown
-
item
command
=
"paymentAccount"
>
<
el
-
button
type
=
"text"
style
=
{{
color
:
'#2776ce'
,
fontWeight
:
'bold'
}}
>
管理付款账户
<
/el-button
>
<
/el-dropdown-item
>
<
/el-dropdown-menu
>
<
/el-dropdown
>
<
/div
>
...
...
@@ -502,7 +526,7 @@ export default {
})
},
getStatusList
()
{
get
(
'customer/info/service
StatusL
ist'
)
get
(
'customer/info/service
-status-l
ist'
)
.
then
((
res
)
=>
{
if
(
res
.
code
!==
200
)
return
this
.
serviceStatusLists
=
res
.
data
||
[]
...
...
@@ -533,6 +557,10 @@ export default {
case
'log'
:
this
.
logInfo
(
row
)
break
case
'paymentAccount'
:
this
.
paymentAccountRow
=
row
this
.
paymentAccountDialog
=
true
break
}
},
sizeChange
(
pageSize
)
{
...
...
@@ -546,7 +574,7 @@ export default {
async
getTableList
()
{
this
.
loading
=
true
const
{
pageSize
,
currentPage
}
=
this
.
centerPageOptions
post
(
'customer/info/page
L
ist'
,
{
post
(
'customer/info/page
-l
ist'
,
{
pageSize
,
currentPage
,
...
this
.
searchForm
...
...
@@ -619,8 +647,8 @@ export default {
openErp
:
()
=>
{
url
=
this
.
erpStatus
===
'未开通'
?
'customer/info/open
S
ervice'
:
'customer/info/re
OpenS
ervice'
?
'customer/info/open
-s
ervice'
:
'customer/info/re
-open-s
ervice'
params
.
serviceType
=
1
params
.
customerId
=
editForm
.
id
params
.
domain
=
fullDomain
...
...
@@ -750,7 +778,7 @@ export default {
},
async
logInfo
(
v
)
{
try
{
const
res
=
await
get
(
`customer/info/operation
L
og/
${
v
.
id
}
`
)
const
res
=
await
get
(
`customer/info/operation
-l
og/
${
v
.
id
}
`
)
if
(
res
.
code
!==
200
)
return
this
.
logList
=
res
.
data
||
[]
this
.
logVisible
=
true
...
...
@@ -767,6 +795,18 @@ export default {
display
:
flex
;
overflow
:
hidden
;
}
.order-account-cell
{
font-size
:
12px
;
color
:
#303133
;
.balance,
.recharge
{
color
:
#303133
;
font-weight
:
600
;
}
.separator
{
color
:
#303133
;
}
}
.page_right
{
flex
:
1
;
display
:
flex
;
...
...
src/views/user/paymentAccountManageDialog.vue
0 → 100644
View file @
124f05e2
This diff is collapsed.
Click to expand it.
src/views/user/rechargeRecord.vue
View file @
124f05e2
...
...
@@ -220,7 +220,7 @@
</div>
</div>
</el-tab-pane>
<el-tab-pane
label=
"线下充值
记录
"
name=
"offline"
>
<el-tab-pane
label=
"线下充值
管理
"
name=
"offline"
>
<div
class=
"tab-content"
>
<div
class=
"search"
>
<el-form
:model=
"offlineSearchForm"
size=
"small"
:inline=
"true"
>
...
...
@@ -255,10 +255,10 @@
:value=
"item.code"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"
账户类型
"
>
<el-form-item
label=
"
余额账户
"
>
<el-select
v-model=
"offlineSearchForm.accountType"
placeholder=
"请选择
账户类型
"
placeholder=
"请选择
余额账户
"
clearable
@
change=
"onOfflineFilterChange"
>
<el-option
...
...
@@ -358,7 +358,7 @@
:show-overflow-tooltip=
"true"
/>
<el-table-column
label=
"
账户类型
"
label=
"
余额账户
"
prop=
"accountTypeName"
header-align=
"center"
align=
"center"
...
...
@@ -644,7 +644,7 @@ export default {
this
.
aliPayLoading
=
false
}
},
// 线下充值
记录
// 线下充值
管理
async
loadOfflineData
()
{
const
data
=
{
...
this
.
offlineSearchForm
,
...
...
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