feat(integral-external): 新增寄卖外部免认证三件套页面

This commit is contained in:
danaisuiyuan
2026-05-02 06:13:41 +08:00
parent 49900919c6
commit d8ad6cde20
35 changed files with 3369 additions and 14 deletions

View File

@@ -0,0 +1,297 @@
<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>