298 lines
10 KiB
Vue
298 lines
10 KiB
Vue
<template>
|
||
<div class="divBox relative">
|
||
<!-- 顶部搜索区 -->
|
||
<el-card class="box-card">
|
||
<div class="container">
|
||
<el-form
|
||
ref="searchForm"
|
||
:model="tableFrom"
|
||
inline
|
||
size="small"
|
||
label-width="100px"
|
||
>
|
||
<el-form-item label="用户ID:">
|
||
<el-input
|
||
v-model="tableFrom.uid"
|
||
placeholder="请输入用户ID"
|
||
class="selWidth"
|
||
clearable
|
||
@keyup.enter.native="seachList"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="联系方式:">
|
||
<el-input
|
||
v-model="tableFrom.mobile"
|
||
placeholder="请输入手机号 / 账号"
|
||
class="selWidth"
|
||
clearable
|
||
@keyup.enter.native="seachList"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="上级ID:">
|
||
<el-input
|
||
v-model="tableFrom.pid"
|
||
placeholder="请输入上级ID"
|
||
class="selWidth"
|
||
clearable
|
||
@keyup.enter.native="seachList"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" icon="el-icon-search" @click="seachList">查询</el-button>
|
||
<el-button icon="el-icon-refresh-left" @click="resetHandler">重置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
</el-card>
|
||
|
||
<!-- 主表 -->
|
||
<el-card class="box-card mt10">
|
||
<div class="header-actions">
|
||
<el-button size="mini" icon="el-icon-refresh" circle @click="getList" />
|
||
<el-button size="mini" icon="el-icon-upload2" circle @click="exportCsv" />
|
||
</div>
|
||
|
||
<el-table
|
||
v-loading="listLoading"
|
||
:data="tableData.data"
|
||
size="mini"
|
||
class="table"
|
||
highlight-current-row
|
||
:header-cell-style="{ fontWeight: 'bold' }"
|
||
>
|
||
<el-table-column prop="id" label="用户ID" min-width="80" />
|
||
<el-table-column prop="username" label="账号" min-width="130">
|
||
<template slot-scope="scope">
|
||
<span>{{ scope.row.username || scope.row.mobile || '-' }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="nickname" label="昵称" min-width="100" show-overflow-tooltip>
|
||
<template slot-scope="scope">
|
||
<span>{{ scope.row.nickname || '-' }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="昨日卖/今日买" min-width="120" align="center">
|
||
<template slot-scope="scope">
|
||
<span>{{ scope.row.prevSellCnt || 0 }}/{{ scope.row.todayBuyCnt || 0 }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="合同" min-width="80" align="center">
|
||
<template slot-scope="scope">
|
||
<el-link
|
||
v-if="scope.row.contract"
|
||
type="primary"
|
||
:underline="false"
|
||
@click="openContract(scope.row.contract)"
|
||
>查看</el-link>
|
||
<span v-else>-</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="mobile" label="联系方式" min-width="130" />
|
||
<el-table-column label="上级ID" min-width="90" align="center">
|
||
<template slot-scope="scope">
|
||
<span>{{ scope.row.pid || '-' }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="最高可抢单数" min-width="110" align="center">
|
||
<template slot-scope="scope">
|
||
<span>{{ scope.row.maxOrder ? scope.row.maxOrder : '未设置' }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="todayBuyAmount" label="今日购买总金额" min-width="130" align="right" />
|
||
<el-table-column prop="todaySellAmount" label="今日卖出总金额" min-width="130" align="right" />
|
||
<el-table-column label="用户等级" min-width="100" align="center">
|
||
<template slot-scope="scope">
|
||
<span :style="{ color: levelColor(scope.row.level) }">
|
||
{{ scope.row.levelName || '普通用户' }}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="money" label="余额" min-width="100" align="right" />
|
||
<el-table-column prop="coupon" label="优惠券" min-width="100" align="right" />
|
||
<el-table-column prop="selfBonus" label="个人奖金" min-width="100" align="right" />
|
||
<el-table-column prop="shareBonus" label="推广奖金" min-width="100" align="right" />
|
||
<el-table-column label="状态" min-width="80" align="center">
|
||
<template slot-scope="scope">
|
||
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'" size="mini">
|
||
{{ scope.row.statusStr || (scope.row.status === 1 ? '正常' : '禁用') }}
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="updatedAt" label="更新时间" min-width="160" show-overflow-tooltip />
|
||
<el-table-column label="操作" min-width="160" fixed="right" align="center">
|
||
<template slot-scope="scope">
|
||
<el-button type="text" size="small" @click="onEditPid(scope.row)">修改上级</el-button>
|
||
<el-button type="text" size="small" @click="onContractRenew(scope.row)">合同重签</el-button>
|
||
<el-button type="text" size="small" @click="onEdit(scope.row)">编辑</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<div class="block mt20">
|
||
<el-pagination
|
||
:page-sizes="[15, 30, 45, 60]"
|
||
:page-size="tableFrom.limit"
|
||
:current-page="tableFrom.page"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
:total="tableData.total"
|
||
@size-change="handleSizeChange"
|
||
@current-change="handleCurrentChange"
|
||
/>
|
||
</div>
|
||
</el-card>
|
||
|
||
<!-- 写操作提示对话框(外部页面默认不直接修改资金类字段) -->
|
||
<el-dialog title="提示" :visible.sync="writeTipVisible" width="380px" append-to-body>
|
||
<span>{{ writeTipText }}</span>
|
||
<span slot="footer">
|
||
<el-button type="primary" size="small" @click="writeTipVisible = false">知道了</el-button>
|
||
</span>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { getExternalGrabUserList } from '@/api/integralExternal';
|
||
|
||
export default {
|
||
name: 'IntegralExternalGrabUser',
|
||
data() {
|
||
return {
|
||
listLoading: false,
|
||
tableData: { data: [], total: 0 },
|
||
tableFrom: {
|
||
uid: '',
|
||
mobile: '',
|
||
pid: '',
|
||
page: 1,
|
||
limit: 15,
|
||
},
|
||
writeTipVisible: false,
|
||
writeTipText: '',
|
||
};
|
||
},
|
||
mounted() {
|
||
this.getList();
|
||
},
|
||
methods: {
|
||
getList() {
|
||
this.listLoading = true;
|
||
const params = { ...this.tableFrom };
|
||
// 空字段不发送
|
||
Object.keys(params).forEach((k) => {
|
||
if (params[k] === '' || params[k] === null) delete params[k];
|
||
});
|
||
getExternalGrabUserList(params)
|
||
.then((res) => {
|
||
this.tableData.data = res.list || [];
|
||
this.tableData.total = res.total || 0;
|
||
})
|
||
.catch(() => {})
|
||
.finally(() => {
|
||
this.listLoading = false;
|
||
});
|
||
},
|
||
seachList() {
|
||
this.tableFrom.page = 1;
|
||
this.getList();
|
||
},
|
||
resetHandler() {
|
||
this.tableFrom = { uid: '', mobile: '', pid: '', page: 1, limit: 15 };
|
||
this.getList();
|
||
},
|
||
handleSizeChange(val) {
|
||
this.tableFrom.limit = val;
|
||
this.getList();
|
||
},
|
||
handleCurrentChange(val) {
|
||
this.tableFrom.page = val;
|
||
this.getList();
|
||
},
|
||
openContract(url) {
|
||
if (!url) return;
|
||
window.open(url, '_blank');
|
||
},
|
||
levelColor(level) {
|
||
switch (level) {
|
||
case 2:
|
||
return '#E6A23C';
|
||
case 3:
|
||
return '#67C23A';
|
||
default:
|
||
return '#409EFF';
|
||
}
|
||
},
|
||
onEditPid() {
|
||
this.writeTipText = '请在管理后台「用户管理」中修改上级;本页面不支持写操作。';
|
||
this.writeTipVisible = true;
|
||
},
|
||
onContractRenew() {
|
||
this.writeTipText = '请在管理后台「用户管理」中进行合同重签;本页面不支持写操作。';
|
||
this.writeTipVisible = true;
|
||
},
|
||
onEdit() {
|
||
this.writeTipText = '请在管理后台「用户管理」中编辑;本页面不支持写操作。';
|
||
this.writeTipVisible = true;
|
||
},
|
||
/**
|
||
* 简易 CSV 导出(仅当前页)
|
||
* 生产环境如需全量导出建议改为后端 /grab-user/list/export
|
||
*/
|
||
exportCsv() {
|
||
const rows = this.tableData.data || [];
|
||
if (rows.length === 0) {
|
||
this.$message.info('当前页没有数据可导出');
|
||
return;
|
||
}
|
||
const headers = [
|
||
'用户ID', '账号', '昵称', '昨日卖/今日买', '联系方式', '上级ID',
|
||
'最高可抢单数', '今日购买总金额', '今日卖出总金额', '用户等级',
|
||
'余额', '优惠券', '个人奖金', '推广奖金', '状态', '更新时间',
|
||
];
|
||
const lines = [headers.join(',')];
|
||
rows.forEach((r) => {
|
||
const fields = [
|
||
r.id,
|
||
r.username || r.mobile || '',
|
||
r.nickname || '',
|
||
`${r.prevSellCnt || 0}/${r.todayBuyCnt || 0}`,
|
||
r.mobile || '',
|
||
r.pid || '',
|
||
r.maxOrder || '',
|
||
r.todayBuyAmount || '0',
|
||
r.todaySellAmount || '0',
|
||
r.levelName || '普通用户',
|
||
r.money || '0',
|
||
r.coupon || '0',
|
||
r.selfBonus || '0',
|
||
r.shareBonus || '0',
|
||
r.statusStr || (r.status === 1 ? '正常' : '禁用'),
|
||
r.updatedAt || '',
|
||
].map((v) => `"${String(v).replace(/"/g, '""')}"`);
|
||
lines.push(fields.join(','));
|
||
});
|
||
const blob = new Blob(['' + lines.join('\n')], { type: 'text/csv;charset=utf-8;' });
|
||
const url = URL.createObjectURL(blob);
|
||
const a = document.createElement('a');
|
||
a.href = url;
|
||
a.download = `今日抢单用户_${new Date().toISOString().slice(0, 10)}.csv`;
|
||
document.body.appendChild(a);
|
||
a.click();
|
||
document.body.removeChild(a);
|
||
URL.revokeObjectURL(url);
|
||
},
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.mt10 { margin-top: 10px; }
|
||
.mt20 { margin-top: 20px; }
|
||
.selWidth { width: 220px; }
|
||
.header-actions {
|
||
text-align: right;
|
||
margin-bottom: 8px;
|
||
}
|
||
.block { text-align: right; }
|
||
</style>
|