新增
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
<template>
|
||||
<popup
|
||||
ref="popupRef"
|
||||
title="余额调整"
|
||||
width="500px"
|
||||
@confirm="handleConfirm"
|
||||
:async="true"
|
||||
@close="popupClose"
|
||||
>
|
||||
<div class="pr-8">
|
||||
<el-form ref="formRef" :model="formData" label-width="120px" :rules="formRules">
|
||||
<el-form-item label="当前余额">¥ {{ value }} </el-form-item>
|
||||
<el-form-item label="余额增减" required prop="action">
|
||||
<el-radio-group v-model="formData.action">
|
||||
<el-radio :value="1">增加余额</el-radio>
|
||||
<el-radio :value="2">扣减余额</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="调整余额" prop="num">
|
||||
<el-input
|
||||
:model-value="formData.num"
|
||||
placeholder="请输入调整的金额"
|
||||
type="number"
|
||||
@input="numberValidate"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="调整后余额"> ¥ {{ adjustmentMoney }} </el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="formData.remark" type="textarea" :rows="4" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</popup>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
|
||||
import Popup from '@/components/popup/index.vue'
|
||||
import feedback from '@/utils/feedback'
|
||||
|
||||
const formRef = shallowRef<FormInstance>()
|
||||
const props = defineProps({
|
||||
show: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
value: {
|
||||
type: [Number, String],
|
||||
required: true
|
||||
}
|
||||
})
|
||||
const emit = defineEmits<{
|
||||
(event: 'update:show', value: boolean): void
|
||||
(event: 'confirm', value: any): void
|
||||
}>()
|
||||
const formData = reactive({
|
||||
action: 1, //变动类型 1-增加 2-减少
|
||||
num: '',
|
||||
remark: ''
|
||||
})
|
||||
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
||||
|
||||
const adjustmentMoney = computed(() => {
|
||||
return Number(props.value) + Number(formData.num) * (formData.action == 1 ? 1 : -1)
|
||||
})
|
||||
|
||||
const formRules: FormRules = {
|
||||
num: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入调整的金额'
|
||||
}
|
||||
]
|
||||
}
|
||||
const numberValidate = (value: string) => {
|
||||
if (value.includes('-')) {
|
||||
return feedback.msgError('请输入正整数')
|
||||
}
|
||||
formData.num = value
|
||||
}
|
||||
const handleConfirm = async () => {
|
||||
await formRef.value?.validate()
|
||||
emit('confirm', formData)
|
||||
}
|
||||
|
||||
const popupClose = () => {
|
||||
emit('update:show', false)
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
watch(
|
||||
() => props.show,
|
||||
(val) => {
|
||||
if (val) {
|
||||
popupRef.value?.open()
|
||||
} else {
|
||||
popupRef.value?.close()
|
||||
}
|
||||
}
|
||||
)
|
||||
watch(adjustmentMoney, (val) => {
|
||||
if (val < 0) {
|
||||
feedback.msgError('调整后余额需大于0')
|
||||
formData.num = ''
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,170 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-card class="!border-none" shadow="never">
|
||||
<el-page-header content="用户详情" @back="$router.back()" />
|
||||
</el-card>
|
||||
<el-card class="mt-4 !border-none" header="基本资料" shadow="never">
|
||||
<el-form ref="formRef" class="ls-form" :model="formData" label-width="120px">
|
||||
<div class="bg-page flex py-5 mb-10 items-center">
|
||||
<div class="basis-40 flex flex-col justify-center items-center">
|
||||
<div class="mb-2 text-tx-regular">用户头像</div>
|
||||
<el-avatar :src="formData.avatar" :size="58" />
|
||||
</div>
|
||||
<div class="basis-40 flex flex-col justify-center items-center">
|
||||
<div class="text-tx-regular">账户余额</div>
|
||||
<div class="mt-2 flex items-center">
|
||||
¥{{ formData.user_money }}
|
||||
<el-button
|
||||
v-perms="['user.user/adjustMoney']"
|
||||
type="primary"
|
||||
link
|
||||
@click="handleAdjust(formData.user_money)"
|
||||
>
|
||||
调整
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-form-item label="用户昵称:">
|
||||
{{ formData.nickname }}
|
||||
</el-form-item>
|
||||
<el-form-item label="账号:">
|
||||
{{ formData.account }}
|
||||
<popover-input
|
||||
class="ml-[10px]"
|
||||
@confirm="handleEdit($event, 'account')"
|
||||
:limit="32"
|
||||
v-perms="['user.user/edit']"
|
||||
>
|
||||
<el-button type="primary" link>
|
||||
<icon name="el-icon-EditPen" />
|
||||
</el-button>
|
||||
</popover-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="真实姓名:">
|
||||
{{ formData.real_name || '-' }}
|
||||
<popover-input
|
||||
class="ml-[10px]"
|
||||
@confirm="handleEdit($event, 'real_name')"
|
||||
:limit="32"
|
||||
v-perms="['user.user/edit']"
|
||||
>
|
||||
<el-button type="primary" link>
|
||||
<icon name="el-icon-EditPen" />
|
||||
</el-button>
|
||||
</popover-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="性别:">
|
||||
{{ formData.sex }}
|
||||
<popover-input
|
||||
class="ml-[10px]"
|
||||
type="select"
|
||||
:options="[
|
||||
{
|
||||
label: '未知',
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
label: '男',
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: '女',
|
||||
value: 2
|
||||
}
|
||||
]"
|
||||
@confirm="handleEdit($event, 'sex')"
|
||||
v-perms="['user.user/edit']"
|
||||
>
|
||||
<el-button type="primary" link>
|
||||
<icon name="el-icon-EditPen" />
|
||||
</el-button>
|
||||
</popover-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="联系电话:">
|
||||
{{ formData.mobile || '-' }}
|
||||
<popover-input
|
||||
class="ml-[10px]"
|
||||
type="number"
|
||||
@confirm="handleEdit($event, 'mobile')"
|
||||
v-perms="['user.user/edit']"
|
||||
>
|
||||
<el-button type="primary" link>
|
||||
<icon name="el-icon-EditPen" />
|
||||
</el-button>
|
||||
</popover-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="注册来源:"> {{ formData.channel }} </el-form-item>
|
||||
<el-form-item label="注册时间:"> {{ formData.create_time }} </el-form-item>
|
||||
<el-form-item label="最近登录时间:"> {{ formData.login_time }} </el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<account-adjust
|
||||
v-model:show="adjustState.show"
|
||||
:value="adjustState.value"
|
||||
@confirm="handleConfirmAdjust"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="consumerDetail">
|
||||
import type { FormInstance } from 'element-plus'
|
||||
|
||||
import { adjustMoney, getUserDetail, userEdit } from '@/api/consumer'
|
||||
import { isEmpty } from '@/utils/util'
|
||||
|
||||
import AccountAdjust from '../components/account-adjust.vue'
|
||||
|
||||
const route = useRoute()
|
||||
const formData = reactive({
|
||||
avatar: '',
|
||||
channel: '',
|
||||
create_time: '',
|
||||
login_time: '',
|
||||
mobile: '',
|
||||
nickname: '',
|
||||
real_name: 0,
|
||||
sex: 0,
|
||||
sn: '',
|
||||
account: '',
|
||||
user_money: ''
|
||||
})
|
||||
|
||||
const adjustState = reactive({
|
||||
show: false,
|
||||
value: ''
|
||||
})
|
||||
const formRef = shallowRef<FormInstance>()
|
||||
|
||||
const getDetails = async () => {
|
||||
const data = await getUserDetail({
|
||||
id: route.query.id
|
||||
})
|
||||
Object.keys(formData).forEach((key) => {
|
||||
//@ts-ignore
|
||||
formData[key] = data[key]
|
||||
})
|
||||
}
|
||||
|
||||
const handleEdit = async (value: string, field: string) => {
|
||||
if (isEmpty(value)) return
|
||||
await userEdit({
|
||||
id: route.query.id,
|
||||
field,
|
||||
value
|
||||
})
|
||||
getDetails()
|
||||
}
|
||||
|
||||
const handleAdjust = (value: string) => {
|
||||
adjustState.show = true
|
||||
adjustState.value = value
|
||||
}
|
||||
const handleConfirmAdjust = async (value: any) => {
|
||||
await adjustMoney({ user_id: route.query.id, ...value })
|
||||
adjustState.show = false
|
||||
getDetails()
|
||||
}
|
||||
getDetails()
|
||||
</script>
|
||||
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-card class="!border-none" shadow="never">
|
||||
<el-form ref="formRef" class="mb-[-16px]" :model="queryParams" :inline="true">
|
||||
<el-form-item class="w-[280px]" label="用户信息">
|
||||
<el-input
|
||||
v-model="queryParams.keyword"
|
||||
placeholder="账号/昵称/手机号码"
|
||||
clearable
|
||||
@keyup.enter="resetPage"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="注册时间">
|
||||
<daterange-picker
|
||||
v-model:startTime="queryParams.create_time_start"
|
||||
v-model:endTime="queryParams.create_time_end"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="w-[280px]" label="注册来源">
|
||||
<el-select v-model="queryParams.channel">
|
||||
<el-option
|
||||
v-for="(item, key) in ClientMap"
|
||||
:key="key"
|
||||
:label="item"
|
||||
:value="key"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="resetPage">查询</el-button>
|
||||
<el-button @click="resetParams">重置</el-button>
|
||||
<export-data
|
||||
class="ml-2.5"
|
||||
:fetch-fun="getUserList"
|
||||
:params="queryParams"
|
||||
:page-size="pager.size"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<el-card class="!border-none mt-4" shadow="never">
|
||||
<el-table size="large" v-loading="pager.loading" :data="pager.lists">
|
||||
<el-table-column label="头像" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<el-avatar :src="row.avatar" :size="50" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="昵称" prop="nickname" min-width="100" />
|
||||
<el-table-column label="账号" prop="account" min-width="120" />
|
||||
<el-table-column label="手机号码" prop="mobile" min-width="100" />
|
||||
<el-table-column label="注册来源" prop="channel" min-width="100" />
|
||||
<el-table-column label="注册时间" prop="create_time" min-width="120" />
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button v-perms="['user.user/detail']" type="primary" link>
|
||||
<router-link
|
||||
:to="{
|
||||
path: getRoutePath('user.user/detail'),
|
||||
query: {
|
||||
id: row.id
|
||||
}
|
||||
}"
|
||||
>
|
||||
详情
|
||||
</router-link>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="flex justify-end mt-4">
|
||||
<pagination v-model="pager" @change="getLists" />
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup name="consumerLists">
|
||||
import { getUserList } from '@/api/consumer'
|
||||
import { ClientMap } from '@/enums/appEnums'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import { getRoutePath } from '@/router'
|
||||
|
||||
const queryParams = reactive({
|
||||
keyword: '',
|
||||
channel: '',
|
||||
create_time_start: '',
|
||||
create_time_end: ''
|
||||
})
|
||||
|
||||
const { pager, getLists, resetPage, resetParams } = usePaging({
|
||||
fetchFun: getUserList,
|
||||
params: queryParams
|
||||
})
|
||||
onActivated(() => {
|
||||
getLists()
|
||||
})
|
||||
|
||||
getLists()
|
||||
</script>
|
||||
Reference in New Issue
Block a user