Commit 124f05e2 by zhuzhequan

feat:需求功能完善

parent 6b13a992
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: '充值失败'
}
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 })
}
......@@ -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 }}
......
......@@ -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/serviceStatusList')
get('customer/info/service-status-list')
.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/pageList', {
post('customer/info/page-list', {
pageSize,
currentPage,
...this.searchForm
......@@ -619,8 +647,8 @@ export default {
openErp: () => {
url =
this.erpStatus === '未开通'
? 'customer/info/openService'
: 'customer/info/reOpenService'
? 'customer/info/open-service'
: 'customer/info/re-open-service'
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/operationLog/${v.id}`)
const res = await get(`customer/info/operation-log/${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;
......
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment