feat: refine member and trade management
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="会员列表"
|
||||
>会员资料默认脱敏展示;余额、禁用与奖励均通过审批流程处理。</n-card
|
||||
>会员资料默认脱敏展示;余额修改会自动保留账变流水。</n-card
|
||||
>
|
||||
</div>
|
||||
<n-card :bordered="false" class="proCard">
|
||||
@@ -45,15 +45,9 @@
|
||||
:model="editForm"
|
||||
:rules="editRules"
|
||||
label-placement="left"
|
||||
label-width="100"
|
||||
label-width="88"
|
||||
>
|
||||
<n-form-item label="标记">
|
||||
<n-checkbox
|
||||
:checked="editForm.isTestAccount === 1"
|
||||
@update:checked="editForm.isTestAccount = $event ? 1 : 2"
|
||||
>标记</n-checkbox
|
||||
>
|
||||
</n-form-item>
|
||||
<div class="edit-form-grid">
|
||||
<n-form-item label="用户名称" path="username" required
|
||||
><n-input v-model:value="editForm.username" placeholder="请输入用户名称"
|
||||
/></n-form-item>
|
||||
@@ -62,8 +56,13 @@
|
||||
v-model:value="editForm.mobile"
|
||||
:placeholder="editForm.currentMobile || '留空不修改'"
|
||||
/></n-form-item>
|
||||
<n-form-item label="账户余额"
|
||||
><n-input :value="money(editForm.availableAmount)" disabled
|
||||
<n-form-item label="账户余额" path="availableAmountYuan"
|
||||
><n-input-number
|
||||
v-model:value="editForm.availableAmountYuan"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
class="form-number"
|
||||
placeholder="请输入账户余额"
|
||||
/></n-form-item>
|
||||
<n-form-item label="冻结金额"
|
||||
><n-input :value="money(editForm.frozenAmount)" disabled
|
||||
@@ -108,6 +107,17 @@
|
||||
:max="1000"
|
||||
class="form-number"
|
||||
/></n-form-item>
|
||||
<n-form-item class="edit-mark-item">
|
||||
<n-alert type="warning" :show-icon="true" class="edit-mark-alert">
|
||||
<n-checkbox
|
||||
:checked="editForm.isTestAccount === 1"
|
||||
@update:checked="editForm.isTestAccount = $event ? 1 : 2"
|
||||
>标记为假人账号</n-checkbox
|
||||
>
|
||||
<div class="edit-mark-hint">标记后该会员将按模拟账号处理,请确认后再保存。</div>
|
||||
</n-alert>
|
||||
</n-form-item>
|
||||
</div>
|
||||
</n-form>
|
||||
</n-spin>
|
||||
<template #action
|
||||
@@ -476,12 +486,19 @@
|
||||
validator: () => true,
|
||||
trigger: ['input', 'blur'],
|
||||
},
|
||||
availableAmountYuan: {
|
||||
validator: (_rule, value) =>
|
||||
value !== null && Number.isFinite(Number(value)) && Number(value) >= 0
|
||||
? true
|
||||
: new Error('账户余额不能为空或小于0'),
|
||||
trigger: ['input', 'blur'],
|
||||
},
|
||||
password: {
|
||||
validator: (_rule, value) => {
|
||||
const text = String(value || '');
|
||||
if (!text) return true;
|
||||
if (text.length < 8 || !/[A-Za-z]/.test(text) || !/\d/.test(text))
|
||||
return new Error('密码至少8位且必须同时包含字母和数字');
|
||||
if (text.length < 6 || text.length > 64)
|
||||
return new Error('密码长度为6到64个字符');
|
||||
return true;
|
||||
},
|
||||
trigger: ['input', 'blur'],
|
||||
@@ -627,6 +644,7 @@
|
||||
memberCategory: row?.memberCategory || 1,
|
||||
isTestAccount: row?.isTestAccount || 2,
|
||||
availableAmount: row?.availableAmount || 0,
|
||||
availableAmountYuan: (row?.availableAmount || 0) / 100,
|
||||
frozenAmount: row?.frozenAmount || 0,
|
||||
});
|
||||
showEdit.value = true;
|
||||
@@ -638,6 +656,7 @@
|
||||
riskStatus: data.riskStatus || 1,
|
||||
creditScore: data.creditScore ?? 100,
|
||||
availableAmount: data.availableAmount || 0,
|
||||
availableAmountYuan: (data.availableAmount || 0) / 100,
|
||||
frozenAmount: data.frozenAmount || 0,
|
||||
currentMobile: data.mobile || row.mobile,
|
||||
});
|
||||
@@ -654,7 +673,10 @@
|
||||
saving.value = true;
|
||||
try {
|
||||
editForm.memberCategory = editForm.isTestAccount === 1 ? 2 : 1;
|
||||
await Edit(editForm);
|
||||
await Edit({
|
||||
...editForm,
|
||||
availableAmount: Math.round(Number(editForm.availableAmountYuan) * 100),
|
||||
});
|
||||
message.success('保存成功');
|
||||
showEdit.value = false;
|
||||
reloadTable();
|
||||
@@ -1090,7 +1112,7 @@
|
||||
max-width: 94vw;
|
||||
}
|
||||
:global(.edit-modal) {
|
||||
width: 720px;
|
||||
width: 700px;
|
||||
max-width: 92vw;
|
||||
}
|
||||
:global(.related-modal) {
|
||||
@@ -1100,6 +1122,23 @@
|
||||
.form-number {
|
||||
width: 100%;
|
||||
}
|
||||
.edit-form-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
column-gap: 20px;
|
||||
}
|
||||
.edit-mark-item {
|
||||
grid-column: 1 / -1;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.edit-mark-alert {
|
||||
width: 100%;
|
||||
}
|
||||
.edit-mark-hint {
|
||||
margin-top: 4px;
|
||||
color: #d97706;
|
||||
font-size: 12px;
|
||||
}
|
||||
.upload-title {
|
||||
margin-bottom: 8px;
|
||||
color: var(--n-label-text-color);
|
||||
@@ -1160,4 +1199,12 @@
|
||||
.action-column-scrollbar::-webkit-scrollbar-thumb:hover {
|
||||
background: #8c94a1;
|
||||
}
|
||||
@media (max-width: 680px) {
|
||||
.edit-form-grid {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
.edit-mark-item {
|
||||
grid-column: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
show.value = true;
|
||||
productLoading.value = true;
|
||||
try {
|
||||
const result: any = await ProductList({ page: 1, perPage: 500 });
|
||||
const result: any = await ProductList({ page: 1, perPage: 200 });
|
||||
productOptions.value = (result.list || []).map((item) => ({
|
||||
label: `${item.name}(${item.productNo})`,
|
||||
value: item.id,
|
||||
|
||||
@@ -22,6 +22,13 @@ const yuan = (value) => `¥${((value || 0) / 100).toFixed(2)}`;
|
||||
export const columns = [
|
||||
{ title: '订单号', key: 'rechargeNo', width: 210 },
|
||||
{ title: '真实姓名', key: 'realNameMask', width: 110 },
|
||||
{
|
||||
title: '备注',
|
||||
key: 'reviewReason',
|
||||
width: 180,
|
||||
ellipsis: { tooltip: true },
|
||||
render: (row) => row.reviewReason || row.remark || dict.getLabel('rechargeStatus', row.rechargeStatus) || '-',
|
||||
},
|
||||
{ title: '手机号', key: 'mobile', width: 130 },
|
||||
{ title: '用户余额', key: 'availableAmount', width: 120, render: (row) => yuan(row.availableAmount) },
|
||||
{ title: '交易金额', key: 'requestAmount', width: 120, render: (row) => yuan(row.requestAmount) },
|
||||
@@ -35,13 +42,6 @@ export const columns = [
|
||||
{ title: '支付方式', key: 'channelName', width: 120 },
|
||||
{ title: '类型', key: 'rechargeType', width: 100, render: (row) => tag('rechargeType', row.rechargeType) },
|
||||
{ title: '处理时间', key: 'reviewedAt', width: 180 },
|
||||
{
|
||||
title: '备注',
|
||||
key: 'reviewReason',
|
||||
width: 180,
|
||||
ellipsis: { tooltip: true },
|
||||
render: (row) => row.reviewReason || row.remark || dict.getLabel('rechargeStatus', row.rechargeStatus) || '-',
|
||||
},
|
||||
];
|
||||
|
||||
export const loadOptions = () =>
|
||||
|
||||
Reference in New Issue
Block a user