feat: support charge for user
This commit is contained in:
@@ -41,3 +41,16 @@ func (ctl *users) Show(ctx fiber.Ctx, id int64) (*model.Users, error) {
|
||||
func (ctl *users) Articles(ctx fiber.Ctx, id int64, pagination *requests.Pagination) (*requests.Pager, error) {
|
||||
return models.Posts.Bought(ctx.Context(), id, pagination)
|
||||
}
|
||||
|
||||
type UserBalance struct {
|
||||
Balance int64 `json:"balance"`
|
||||
}
|
||||
|
||||
// Balance
|
||||
//
|
||||
// @Router /admin/users/:id/balance [post]
|
||||
// @Bind id path
|
||||
// @Bind balance body
|
||||
func (ctl *users) Balance(ctx fiber.Ctx, id int64, balance *UserBalance) error {
|
||||
return models.Users.AddBalance(ctx.Context(), id, balance.Balance)
|
||||
}
|
||||
|
||||
@@ -13,6 +13,11 @@ export const userService = {
|
||||
searchUser(id) {
|
||||
return httpClient.get(`/admin/users/${id}`);
|
||||
},
|
||||
userBalance(id, balance) {
|
||||
return httpClient.post(`/admin/users/${id}/balance`, {
|
||||
balance
|
||||
});
|
||||
},
|
||||
getUser(id) {
|
||||
return httpClient.get(`/admin/users/${id}`);
|
||||
},
|
||||
|
||||
@@ -72,20 +72,29 @@ const onSearch = (event) => {
|
||||
}, 300);
|
||||
};
|
||||
|
||||
const handleDelete = (user) => {
|
||||
const handleRecharge = (user) => {
|
||||
confirm.require({
|
||||
message: `确定要删除用户 "${user.username}" 吗?`,
|
||||
header: '确认删除',
|
||||
message: `确定要为用户ID ${user.id}: "${user.username}" 充值吗?`,
|
||||
header: '确认充值',
|
||||
icon: 'pi pi-exclamation-triangle',
|
||||
acceptClass: 'p-button-danger',
|
||||
acceptClass: 'p-button-success',
|
||||
accept: async () => {
|
||||
try {
|
||||
await userService.deleteUser(user.id);
|
||||
toast.add({ severity: 'success', summary: '成功', detail: '用户已删除', life: 3000 });
|
||||
|
||||
const amount = prompt('请输入充值金额(元):');
|
||||
if (!amount) return;
|
||||
const amountInCents = Math.floor(parseFloat(amount) * 100);
|
||||
if (isNaN(amountInCents) || amountInCents <= 0) {
|
||||
toast.add({ severity: 'error', summary: '错误', detail: '请输入有效的金额', life: 3000 });
|
||||
return;
|
||||
}
|
||||
|
||||
await userService.userBalance(user.id, amountInCents);
|
||||
toast.add({ severity: 'success', summary: '成功', detail: '用户已充值', life: 3000 });
|
||||
fetchUsers();
|
||||
} catch (error) {
|
||||
console.error('Failed to delete user:', error);
|
||||
toast.add({ severity: 'error', summary: '错误', detail: '删除用户失败', life: 3000 });
|
||||
console.error('Failed to recharge user:', error);
|
||||
toast.add({ severity: 'error', summary: '错误', detail: '充值用户失败', life: 3000 });
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -131,6 +140,12 @@ onMounted(() => {
|
||||
|
||||
<Column field="id" header="ID" sortable></Column>
|
||||
|
||||
<Column field="balance" header="余额" sortable>
|
||||
<template #body="{ data }">
|
||||
¥{{ (data.balance / 100).toFixed(2) }}
|
||||
</template>
|
||||
</Column>
|
||||
|
||||
<Column field="username" header="用户名" sortable>
|
||||
<template #body="{ data }">
|
||||
<div class="flex items-center space-x-3">
|
||||
@@ -170,8 +185,8 @@ onMounted(() => {
|
||||
<Column header="操作" :exportable="false" style="min-width:8rem">
|
||||
<template #body="{ data }">
|
||||
<div class="flex justify-center space-x-2">
|
||||
<Button icon="pi pi-trash" rounded text severity="danger" @click="handleDelete(data)"
|
||||
aria-label="删除" />
|
||||
<Button icon="pi pi-refresh" rounded text severity="success" @click="handleRecharge(data)"
|
||||
aria-label="充值" />
|
||||
</div>
|
||||
</template>
|
||||
</Column>
|
||||
|
||||
Reference in New Issue
Block a user