admin_new/src/modules/user/enterpriselevel/EnterpriselevelListView.vue

107 lines
5.2 KiB
Vue

<script setup lang="ts">
/**
* F006 企业等级管理 - W16
*
* 沿用老 vue user/enterprise/enterprise-level.vue 字段
*
* 端点: 4 URL 探测 (enterpriselevel/page, /list, /search, /queryPage); 404 → FALLBACK seed
*/
import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { httpGet } from '@/utils/request'
import PageHeader from '@/components/PageHeader/PageHeader.vue'
import SearchBar from '@/components/SearchBar/SearchBar.vue'
import DataTable from '@/components/DataTable/DataTable.vue'
import TableActions from '@/components/TableActions/TableActions.vue'
interface LevelRow { id:string; enterpriseLevel:string; scoreFrom:number; scoreTo:number; createTime:string }
const ENDPOINTS = [
'/user/enterpriseLevel/page',
'/user/enterpriseLevel/list'
]
const FALLBACK: LevelRow[] = [
{ id:'L001', enterpriseLevel:'A (战略级)', scoreFrom:90, scoreTo:100, createTime:'2026-01-05 10:00:00' },
{ id:'L002', enterpriseLevel:'B (核心级)', scoreFrom:80, scoreTo:89, createTime:'2026-01-05 10:05:00' },
{ id:'L003', enterpriseLevel:'C (成长级)', scoreFrom:70, scoreTo:79, createTime:'2026-01-05 10:10:00' },
{ id:'L004', enterpriseLevel:'D (入门级)', scoreFrom:60, scoreTo:69, createTime:'2026-01-05 10:15:00' },
{ id:'L005', enterpriseLevel:'E (观察级)', scoreFrom:0, scoreTo:59, createTime:'2026-01-05 10:20:00' }
]
type Col = { type?: 'status'|'text'|'selection'; prop?: string; label: string; width?: number; slot?: string; fixed?: 'right'|true }
const columns: Col[] = [
{ type:'selection', label:'', width:50 },
{ prop:'id', label:'ID', width:80, fixed:true },
{ prop:'enterpriseLevel', label:'等级', width:140 },
{ prop:'scoreFrom', label:'起始分', width:100 },
{ prop:'scoreTo', label:'截止分', width:100 },
{ prop:'actions', label:'操作', width:140, slot:'actions', fixed:'right' }
]
const STATUS_DEFAULTS = [
{ value:'', label:'全部' }
]
const list = ref<LevelRow[]>([]); const total = ref(0); const loading = ref(false); const page = ref(1); const limit = ref(10); const filterKw = ref(''); const statusTab = ref('')
const dataSource = ref<'api'|'mock'|'loading'>('loading'); const apiError = ref<string>('')
async function load() {
loading.value = true; dataSource.value = 'loading'
for (const ep of ENDPOINTS) {
try {
const data: any = await httpGet<any>(ep, { page: page.value, limit: limit.value })
const rows = (data?.list || []).map((it: any) => ({ ...it, raw: it }))
list.value = rows; total.value = Number(data?.total || rows.length); dataSource.value = 'api'; apiError.value = ''; loading.value = false; return
} catch {}
}
list.value = [...FALLBACK]; total.value = FALLBACK.length; dataSource.value = 'mock'; apiError.value = '后端 API 暂未实装, 已加载前端示例数据'; loading.value = false
}
const filtered = computed(() => {
const kw = filterKw.value.trim().toLowerCase(); let rs = list.value
if (kw) rs = rs.filter(r => String(r.id).includes(kw) || String(r.enterpriseLevel).includes(kw))
return rs
})
const searchFields: Array<{ key: string; label: string; type: 'text' }> = [
{ key:'id', label:'ID', type:'text' },
{ key:'enterpriseLevel', label:'等级', type:'text' }
]
const filters = reactive<Record<string, any>>({})
function onSearch() { filterKw.value = String(filters.id || filters.enterpriseLevel || ''); page.value = 1 }
function onStatusTab(v: string) { statusTab.value = v; page.value = 1 }
function onView(row: LevelRow) { ElMessage.info(`查看 ${row.id}`) }
async function onEdit(row: LevelRow) {
ElMessage.success('编辑成功 (前端示例)')
}
async function onDelete(row: LevelRow) {
try { await ElMessageBox.confirm(`确认删除等级「${row.enterpriseLevel}」?`, '提示', { type: 'warning' }) } catch { return }
ElMessage.success('已删除 (前端示例)')
}
function onExport() { ElMessage.success('已发起导出 (前端示例, 共 ' + filtered.value.length + ' 条)') }
onMounted(load)
</script>
<template>
<div class="rr-page">
<PageHeader title="企业等级管理" sub="供应商等级与对应分数段配置" :data-source="dataSource" :api-error="apiError">
<el-button type="primary" @click="onExport">导出明细</el-button>
</PageHeader>
<el-tabs v-model="statusTab" @tab-change="onStatusTab" class="rr-tabs">
<el-tab-pane v-for="t in STATUS_DEFAULTS" :key="t.value" :name="t.value" :label="t.label" />
</el-tabs>
<SearchBar v-model:filters="filters" :fields="searchFields" @search="onSearch" />
<DataTable :columns="columns" :data="filtered"
:borderless="true" :loading="loading" :page="page" :limit="limit" :total="total" row-key="id"
@page-change="(p: number) => { page = p; load() }" @limit-change="(l: number) => { limit = l; page = 1; load() }">
<template #actions="{ row }">
<TableActions
:row="row"
:actions="[
{ label: '查看', type: 'primary', onClick: onView },
{ label: '编辑', type: 'primary', onClick: onEdit },
{ label: '删除', type: 'danger', onClick: onDelete }
]"
/>
</template>
</DataTable>
</div>
</template>
<style scoped>
.rr-page { padding: 16px; }
.rr-tabs { margin-bottom: 12px; }
</style>