- P0.1 数据统计首页 (走 /sys/openapi/order/list 真 API, 4 stat 500/¥47M 真值)
- P0.2 supplier/inquiry/inquiry 重定向 /inquiry (2 个 redirect)
- P0.3 /user/user 用户列表 (2284 真实用户)
- P0.4 /other/operateguide 内容列表 (1 条真数据)
- P0.5 /api/lunbo 轮播占位 (后端 404 优雅提示)
- P0.6 /api/help 帮助中心占位 (后端 404 优雅提示)
- P0.7 /sys/region 行政区域树 (省市区 4 级 3000+ 节点)
同步: src/modules/user/{Enterprise,Finance}ListView.vue (Mac 端 working copy 补传)
P0.7 nginx 修复 (conf 改动非本次提交, 见 nginx-vue.conf.bak-20260704-194200):
- 新增 location = /admin/sys/region { rewrite /admin/index.html last; }
- 原因: location /admin/sys/ 代理抢 /admin/sys/region 走 gateway 返 401
- 已 docker compose restart frontend 生效, devbox 端 7 SPA 路径全 200
114 lines
3.1 KiB
Vue
114 lines
3.1 KiB
Vue
<script setup lang="ts">
|
|
/**
|
|
* F006 用户管理 (前台用户列表) - W3.x C P0.3
|
|
* 走 /user/user/page 后端
|
|
*
|
|
* 字段 (从 API 实测):
|
|
* id, nickName, mobile, header (头像 URL)
|
|
* total=2284 真实用户
|
|
*
|
|
* 注意: 老 sys/UserListView 是后台管理员 (/sys/user/*), 这页是前台用户
|
|
*/
|
|
import { onMounted, ref, reactive } from 'vue'
|
|
import { httpGet } from '@/utils/request'
|
|
import DataTable from '@/components/DataTable/DataTable.vue'
|
|
|
|
interface FrontUser {
|
|
id: string
|
|
nickName: string
|
|
mobile: string
|
|
header?: string | null
|
|
raw: any
|
|
}
|
|
|
|
const list = ref<FrontUser[]>([])
|
|
const total = ref(0)
|
|
const loading = ref(false)
|
|
const query = reactive({
|
|
page: 1,
|
|
limit: 20,
|
|
keyword: ''
|
|
})
|
|
|
|
const columns = [
|
|
{ prop: 'id', label: 'ID', width: 80 },
|
|
{ prop: 'nickName', label: '昵称', minWidth: 160 },
|
|
{ prop: 'mobile', label: '手机号', width: 140 },
|
|
{
|
|
prop: 'header',
|
|
label: '头像',
|
|
width: 80,
|
|
formatter: (row: FrontUser) => row.header ? '有' : '无'
|
|
}
|
|
]
|
|
|
|
async function load() {
|
|
loading.value = true
|
|
try {
|
|
const resp: any = await httpGet('/user/user/page', { page: query.page, limit: query.limit })
|
|
if (resp && Array.isArray(resp.list)) {
|
|
list.value = resp.list.map((it: any) => ({
|
|
id: it.id,
|
|
nickName: it.nickName || '--',
|
|
mobile: it.mobile || '--',
|
|
header: it.header || null,
|
|
raw: it
|
|
}))
|
|
total.value = Number(resp.total || 0)
|
|
} else {
|
|
list.value = []
|
|
total.value = 0
|
|
}
|
|
} catch (e) {
|
|
list.value = []
|
|
total.value = 0
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
function onPageChange(p: number) { query.page = p; load() }
|
|
function onSearch() { query.page = 1; load() }
|
|
|
|
onMounted(load)
|
|
</script>
|
|
|
|
<template>
|
|
<div class="rr-page">
|
|
<div class="rr-page-header">
|
|
<div>
|
|
<h2 class="rr-page-title">用户列表</h2>
|
|
<p class="rr-page-sub">前台注册用户(共 {{ total }} 个)</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="rr-card">
|
|
<div class="rr-toolbar">
|
|
<el-input v-model="query.keyword" placeholder="搜索手机号/昵称" clearable style="width: 280px;" @keyup.enter="onSearch" />
|
|
<el-button type="primary" :icon="'Search'" @click="onSearch">搜索</el-button>
|
|
</div>
|
|
<DataTable
|
|
:columns="columns"
|
|
:data="list"
|
|
:loading="loading"
|
|
:total="total"
|
|
:page="query.page"
|
|
:limit="query.limit"
|
|
:show-pagination="true"
|
|
row-key="id"
|
|
empty-text="暂无用户"
|
|
@page-change="onPageChange"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped lang="scss">
|
|
.rr-page { max-width: 1400px; }
|
|
.rr-page-header { margin-bottom: 20px; }
|
|
.rr-page-title { font-size: 22px; font-weight: 600; letter-spacing: -0.02em; color: var(--ink); margin-bottom: 4px; }
|
|
.rr-page-sub { color: var(--ink-3); font-size: 13px; }
|
|
.rr-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; }
|
|
.rr-toolbar { display: flex; align-items: center; gap: 8px; padding: 14px 20px; border-bottom: 1px solid var(--border); }
|
|
</style>
|