Files
jdt-mer/src/views/user/index1/index.vue
Huakk fe15b87b42
All checks were successful
continuous-integration/drone/push Build is passing
feat(custom):
2024-09-06 21:10:22 +08:00

627 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<CommonPage show-footer :title="$route.title">
<n-row gutter="12">
<n-col :span="24">
<div flex>
<!-- <n-card ml-10 w-200 rounded-5>
<n-statistic label="总积分(含赢)" tabular-nums>
<n-number-animation :from="0" :to="cardData.integral" />
</n-statistic>
</n-card> -->
<n-card ml-10 w-200 rounded-5>
<n-statistic label="用户豆子(留存)" tabular-nums>
<n-number-animation :from="0" :to="cardData.pulse" />
</n-statistic>
</n-card>
<n-card ml-10 w-200 rounded-5>
<n-statistic label="用户积分(留存)" tabular-nums>
<n-number-animation :from="0" :to="cardData.win" />
</n-statistic>
</n-card>
</div>
</n-col>
<n-col :span="24" mt-10>
<div>
<span>筛选状态</span>
<n-radio-group v-model:value="queryData.status">
<n-radio-button
v-for="song in songs"
:key="song.value"
:value="song.value"
:label="song.label"
/>
</n-radio-group>
</div>
</n-col>
<n-col :span="24">
<div mt-10 flex items-center>
<div w-100>关键字搜索</div>
<n-input-group>
<n-select
v-model:value="queryData.selectKey"
:style="{ width: '10%' }"
:options="selectOptions"
placeholder="请选择"
/>
<n-input v-model:value="queryData.word" :style="{ width: '20%' }" />
</n-input-group>
</div>
</n-col>
<n-col :span="10">
<div mt-10 flex items-center>
<span w-100>时间筛选</span>
<n-date-picker
v-model:formatted-value="queryData.time"
value-format="yyyy-MM-dd HH:mm:ss"
type="datetimerange"
clearable
/>
</div>
</n-col>
<n-col :span="24">
<div mt-10>
<n-button type="primary" @click="getList">搜索</n-button>
<n-button ml-10 @click="clear">重置</n-button>
</div>
</n-col>
</n-row>
<n-data-table
class="mt-5"
:loading="loading"
:columns="columns"
:data="data"
:pagination="pagination"
:bordered="false"
remote
@update:sorter="handleSorterChange"
/>
<!-- 用户详情 -->
<n-drawer v-model:show="isDrawer" :width="1000" placement="right" :mask-closable="false">
<n-drawer-content title="用户详情" closable>
<div flex items-center>
<img rounded-full :src="nowRow.avatarUrl" width="70" />
<div ml-10>
<div>昵称{{ nowRow.nickName }}</div>
<div>电话{{ nowRow.phone }}</div>
</div>
</div>
<div mt-10 w-200 flex items-center justify-between text-center>
<div>
<div>用户积分</div>
<div text-red>{{ nowRow.integral }}</div>
</div>
<div>
<div>用户豆子</div>
<div text-red>{{ nowRow.pulse }}</div>
</div>
</div>
<n-tabs v-model:value="tabVal" type="line" animated @update-value="tabsChange">
<n-tab name="1" tab="活动订单"></n-tab>
<n-tab name="2" tab="积分订单"></n-tab>
<n-tab name="3" tab="豆子记录"></n-tab>
<n-tab name="4" tab="积分记录"></n-tab>
<n-tab name="5" tab="推广记录"></n-tab>
</n-tabs>
<n-row gutter="12">
<n-col :span="12">
<div mt-10 flex items-center>
<span w-100>时间筛选</span>
<n-date-picker
v-model:formatted-value="queryData.time"
value-format="yyyy-MM-dd HH:mm:ss"
type="datetimerange"
clearable
/>
</div>
</n-col>
<n-col v-if="tabVal === '4'" :span="10">
<div mt-10 flex items-center>
<span w-100>条件筛选</span>
<n-select
v-model:value="queryData.selectKey"
:style="{ width: '30%' }"
:options="[
{
label: '取消订单',
value: 1,
},
{
label: '支付订单',
value: 2,
},
{
label: '商品赠送',
value: 3,
},
]"
placeholder="请选择类型"
/>
</div>
</n-col>
<n-col :span="4">
<div mt-10>
<n-button type="primary" @click="getTabsList">搜索</n-button>
<n-button ml-10 @click="tabsClear">重置</n-button>
</div>
</n-col>
</n-row>
<n-data-table
class="mt-5"
:columns="tabsColumns"
:loading="tabsLoading"
:data="tabsData"
:pagination="tabsPagination"
:bordered="false"
remote
/>
</n-drawer-content>
</n-drawer>
</CommonPage>
</template>
<script setup>
import api from './api'
import { NDropdown, NButton, NEllipsis } from 'naive-ui'
import TheIcon from '@/components/icon/TheIcon.vue'
const loading = ref(false)
const cardData = ref({
pulse: 0,
integral: 0,
win: 0,
})
const queryData = ref({
status: '',
time: null,
selectKey: null,
word: '',
})
const songs = ref([
{
value: 1,
label: '未使用',
},
{
value: 3,
label: '用户赢',
},
{
value: 4,
label: '用户输',
},
{
value: 5,
label: '已过期',
},
])
const selectOptions = ref([
{
value: 1,
label: '用户昵称',
},
{
value: 2,
label: '手机号',
},
])
const columns = ref([
{
title: 'ID',
align: 'center',
key: 'ID',
},
{
title: '昵称',
align: 'center',
key: 'nickName',
},
{
title: '头像',
align: 'center',
slot: 'avatarUrl',
render(row) {
return h('img', {
src: row.avatarUrl,
style: {
width: '30px',
height: '30px',
borderRadius: '50%',
},
})
},
},
{
title: '电话',
align: 'center',
key: 'phone',
},
{
title: '用户积分',
align: 'center',
key: 'integral',
sorter: true,
sortOrder: false,
},
// {
// title: '赢积分',
// align: 'center',
// key: 'win',
// sorter: true,
// sortOrder: false,
// },
// {
// title: '用户豆子',
// align: 'center',
// key: 'pulse',
// sorter: true,
// sortOrder: false,
// },
{
title: '操作',
align: 'center',
slot: 'action',
render(row) {
return [
h(
NDropdown,
{
trigger: 'click',
options: [
{
label: '用户详情',
key: 1,
},
],
onSelect: (key) => {
switch (key) {
case 1:
openDrawer(row)
break
}
},
},
{
default: () =>
h(
NButton,
{
text: true,
iconPlacement: 'right',
},
{
default: () => '更多',
icon: () =>
h(TheIcon, {
icon: 'ant-design:down-outlined',
}),
}
),
}
),
]
},
},
])
const data = ref([])
const pagination = ref({
page: 1,
pageSize: 10,
itemCount: 0,
onChange: (page) => {
pagination.value.page = page
getList()
},
onUpdatePageSize: (pageSize) => {
pagination.value.pageSize = pageSize
pagination.value.page = 1
getList()
},
})
onMounted(() => {
getList()
})
const getList = async () => {
loading.value = true
try {
const query_data = {
Status: queryData.value.status || '',
StartTime: queryData.value.time === null ? '' : queryData.value.time[0] || '',
EndTime: queryData.value.time === null ? '' : queryData.value.time[1] || '',
}
switch (queryData.value.selectKey) {
case 1:
query_data['Name'] = queryData.value.word
break
case 2:
query_data['Phone'] = queryData.value.word
break
}
const res = await api.getUser({
pageNum: pagination.value.page,
pageSize: pagination.value.pageSize,
...query_data,
})
data.value = res.data.data
pagination.value.itemCount = res.data.total
cardData.value.integral = res.data.total_integral
cardData.value.pulse = res.data.total_pulse
cardData.value.win = res.data.total_win
} catch (error) {
$message.error(error.msg)
}
loading.value = false
}
const clear = () => {
queryData.value = {
time: null,
status: '',
selectKey: null,
word: '',
}
getList()
}
const handleSorterChange = (sorter) => {
if (!loading.value) {
loading.value = true
switch (sorter.columnKey) {
case 'integral':
columns.value[4].sortOrder = !sorter ? false : sorter.order
data.value = data.value.sort((a, b) => {
if (sorter.order === 'descend') return b.integral - a.integral
return a.integral - b.integral
})
break
case 'win':
columns.value[5].sortOrder = !sorter ? false : sorter.order
data.value = data.value.sort((a, b) => {
if (sorter.order === 'descend') return b.win - a.win
return a.win - b.win
})
break
case 'pulse':
columns.value[6].sortOrder = !sorter ? false : sorter.order
data.value = data.value.sort((a, b) => {
if (sorter.order === 'descend') return b.pulse - a.pulse
return a.pulse - b.pulse
})
break
}
loading.value = false
}
}
const isDrawer = ref(false)
const nowRow = ref({})
const tabVal = ref('1')
const tabsLoading = ref(false)
const tabsColumns = ref([])
const tabsData = ref([])
const tabsPagination = ref({
page: 1,
pageSize: 10,
itemCount: 0,
onChange: (page) => {
tabsPagination.value.page = page
getTabsList()
},
})
// eslint-disable-next-line no-unused-vars
const openDrawer = (row) => {
nowRow.value = row
isDrawer.value = true
// getTabsList()
tabsChange()
}
const tabsChange = async (e = '1') => {
tabVal.value = e
tabsData.value = []
tabsColumns.value = []
if (tabVal.value === '1' || tabVal.value === '2') {
tabsColumns.value = [
{
title: '订单号',
align: 'center',
key: 'oid',
},
{
title: '商品封面',
align: 'center',
slot: 'cover',
render: (row) => {
return h('img', {
src: row.cover,
style: {
width: '50px',
height: '50px',
},
})
},
},
{
title: '商品名称',
align: 'center',
slot: 'goods_name',
render: (row) => {
return h(
NEllipsis,
{
style: 'max-width: 240px',
},
{
default: () => row.goods_name,
}
)
},
},
{
title: '商品价格',
align: 'center',
key: 'number',
},
{
title: '订单状态',
align: 'center',
slot: 'status',
render: (row) => {
let nameStr = ''
switch (row.status) {
case 0:
nameStr = '待付款'
break
case 1:
nameStr = '待使用'
break
case 2:
nameStr = '已使用'
break
case 3:
nameStr = '已过期'
}
return h(
'span',
{},
{
default: () => nameStr,
}
)
},
},
{
title: '下单时间',
align: 'center',
key: 'add_time',
},
]
} else if (tabVal.value === '3') {
tabsColumns.value = [
{
title: '订单号',
align: 'center',
key: 'oid',
},
{
title: '商品名称',
align: 'center',
key: 'goods_name',
},
{
title: '消费金额',
align: 'center',
key: 'number',
},
{
title: '下单时间',
align: 'center',
key: 'add_time',
},
]
} else if (tabVal.value === '4') {
tabsColumns.value = [
{
title: '订单号',
align: 'center',
key: 'oid',
},
{
title: '商品名称',
align: 'center',
key: 'goods_name',
},
{
title: '积分',
align: 'center',
key: 'number',
},
{
title: '时间',
align: 'center',
key: 'add_time',
},
]
} else {
tabsColumns.value = [
{
title: '订单号',
align: 'center',
key: 'oid',
},
{
title: '用户昵称',
align: 'center',
key: 'nick_name',
},
{
title: '商品名称',
align: 'center',
key: 'goods_name',
},
{
title: '获得积分',
align: 'center',
key: 'number',
},
{
title: '时间',
align: 'center',
key: 'add_time',
},
]
}
tabsPagination.value.page = 1
getTabsList()
}
const getTabsList = async () => {
tabsLoading.value = true
let res
const data = {
uid: nowRow.value.uid,
pageNum: tabsPagination.value.page,
pageSize: tabsPagination.value.pageSize,
StartTime: queryData.value.time === null ? '' : queryData.value.time[0] || '',
EndTime: queryData.value.time === null ? '' : queryData.value.time[1] || '',
}
switch (tabVal.value) {
case '1':
res = await api.gethdlist(data)
break
case '2':
res = await api.getjflist(data)
break
case '3':
res = await api.getdzJllist(data)
break
case '4':
data['Type'] = queryData.value.selectKey
res = await api.getjfJllist(data)
break
case '5':
res = await api.gettgJllist(data)
break
}
tabsData.value = res.data.data || []
tabsPagination.value.itemCount = res.data.total
tabsLoading.value = false
}
</script>
<style lang="scss" scoped></style>