feat(F006): 企业列表页专业UI升级 - 品牌渐变头像/等级彩色徽章/状态圆点标签(待审核脉冲)/标签前2+溢出/批量栏选中高亮/补审核状态筛选/清理死代码详情弹窗
This commit is contained in:
parent
8be7ca9dc2
commit
508c84e571
@ -1,18 +1,23 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
/**
|
/**
|
||||||
* W18.2 企业列表 — 按项目 UI 规范 (PageHeader/SearchBar/DataTable) + 老 vue 全功能
|
* W18.2 + 2026-08-18 企业列表 — 专业 UI 升级版 (按项目 UI 规范 + 老 vue 全功能)
|
||||||
*
|
*
|
||||||
* 后端端点: ApiEnterpriseController @ /user/enterprise
|
* 后端端点: ApiEnterpriseController @ /user/enterprise
|
||||||
* GET /user/enterprise/page 分页 (EnterpriseDTO 全字段, 支持 enterpriseName/industry/supplierLevel/salesperson/supplierLabel/status/homeShow 过滤)
|
* GET /user/enterprise/page 分页 (EnterpriseDTO 全字段, 支持 enterpriseName/industry/supplierLevel/salesperson/supplierLabel/status/homeShow 过滤)
|
||||||
|
* GET /user/enterprise/checkStatus?id=&status=&failReason= 审核(2通过/3驳回, 支持逗号批量)
|
||||||
|
* POST /user/enterprise/enabled?id= 禁用/启用切换 (后端 @RequestParam 从 query 读)
|
||||||
|
* POST /user/enterprise/showEnterprise?id= 显示/隐藏切换 (query)
|
||||||
|
* GET /user/enterprise/homeShow?id=&homeShow= 首页推荐切换 (query)
|
||||||
*
|
*
|
||||||
* EnterpriseDTO 真实字段 (来源: devbox 编译反编译确认, 2026-07-15):
|
* EnterpriseDTO 真实字段 (来源: devbox 编译反编译确认, 2026-07-15):
|
||||||
* id/enterpriseName/enterpriseLogo/administrator/administratorMobile/industry/supplierLevel
|
* id/enterpriseName/enterpriseLogo/administrator/administratorMobile/industry/supplierLevel
|
||||||
* supplierLabel/salesperson/salespersonMobile/status/createDate/enabled/showFlag/homeShow
|
* supplierLabel/salesperson/salespersonMobile/status/createDate/enabled/showFlag/homeShow
|
||||||
* linkMan/linkMobile/legalMan/email/enterpriseAddress/mainProducts/registerTime/orgNo/failReason
|
* linkMan/linkMobile/legalMan/email/enterpriseAddress/mainProducts/registerTime/orgNo/failReason
|
||||||
*/
|
*/
|
||||||
import { onMounted, ref, reactive } from 'vue'
|
import { onMounted, ref, reactive, computed } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import { User, Clock, Upload, Download, MoreFilled } from '@element-plus/icons-vue'
|
||||||
import { httpGet, httpPost, httpDelete } from '@/utils/request'
|
import { httpGet, httpPost, httpDelete } from '@/utils/request'
|
||||||
import DataTable from '@/components/DataTable/DataTable.vue'
|
import DataTable from '@/components/DataTable/DataTable.vue'
|
||||||
import PageHeader from '@/components/PageHeader/PageHeader.vue'
|
import PageHeader from '@/components/PageHeader/PageHeader.vue'
|
||||||
@ -58,8 +63,7 @@ const loading = ref(false)
|
|||||||
const page = ref(1)
|
const page = ref(1)
|
||||||
const limit = ref(10)
|
const limit = ref(10)
|
||||||
const selectedIds = ref<string[]>([])
|
const selectedIds = ref<string[]>([])
|
||||||
const detailVisible = ref(false)
|
const selectedRows = ref<Enterprise[]>([])
|
||||||
const detailRow = ref<Enterprise | null>(null)
|
|
||||||
|
|
||||||
// ========== 单行审核 ==========
|
// ========== 单行审核 ==========
|
||||||
const auditVisible = ref(false)
|
const auditVisible = ref(false)
|
||||||
@ -82,19 +86,32 @@ const filters = reactive({
|
|||||||
})
|
})
|
||||||
|
|
||||||
// status 映射 (老 vue: 1=待审核,2=已认证,3=已驳回)
|
// status 映射 (老 vue: 1=待审核,2=已认证,3=已驳回)
|
||||||
const STATUS_MAP: Record<string, string> = {
|
const STATUS_META: Record<string, { label: string; color: string; bg: string }> = {
|
||||||
'1': '待审核', '2': '已认证', '3': '已驳回'
|
'1': { label: '待审核', color: '#b45309', bg: '#fef3c7' },
|
||||||
}
|
'2': { label: '已认证', color: '#15803d', bg: '#dcfce7' },
|
||||||
const STATUS_CLASS: Record<string, string> = {
|
'3': { label: '已驳回', color: '#b91c1c', bg: '#fee2e2' }
|
||||||
'1': 'rr-tag-warn', '2': 'rr-tag-ok', '3': 'rr-tag-err'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// supplierLevel 映射 (老 vue: 1=优质,2=钻石,3=金牌,4=银牌,5=铜牌)
|
// supplierLevel 映射 (老 vue: 1=优质,2=钻石,3=金牌,4=银牌,5=铜牌)
|
||||||
const LEVEL_MAP: Record<number, string> = {
|
const LEVEL_META: Record<number, { label: string; color: string; bg: string }> = {
|
||||||
1: '优质供应商', 2: '钻石供应商', 3: '金牌供应商',
|
1: { label: '优质供应商', color: '#92400e', bg: '#fef3c7' },
|
||||||
4: '银牌供应商', 5: '铜牌供应商'
|
2: { label: '钻石供应商', color: '#6d28d9', bg: '#ede9fe' },
|
||||||
|
3: { label: '金牌供应商', color: '#c2410c', bg: '#ffedd5' },
|
||||||
|
4: { label: '银牌供应商', color: '#475569', bg: '#f1f5f9' },
|
||||||
|
5: { label: '铜牌供应商', color: '#a16207', bg: '#fefce8' }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 头像品牌渐变色组 (企业无 logo 时交替使用)
|
||||||
|
const AVATAR_GRADIENTS = [
|
||||||
|
'linear-gradient(135deg, #0b5394, #6fb1e8)',
|
||||||
|
'linear-gradient(135deg, #2563eb, #93c5fd)',
|
||||||
|
'linear-gradient(135deg, #0e7490, #67e8f9)',
|
||||||
|
'linear-gradient(135deg, #7c3aed, #c4b5fd)',
|
||||||
|
'linear-gradient(135deg, #be123c, #fda4af)'
|
||||||
|
]
|
||||||
|
|
||||||
|
const selectedCount = computed(() => selectedIds.value.length)
|
||||||
|
|
||||||
function fmtDate(ts?: string | null) {
|
function fmtDate(ts?: string | null) {
|
||||||
if (!ts) return '--'
|
if (!ts) return '--'
|
||||||
const d = new Date(ts)
|
const d = new Date(ts)
|
||||||
@ -110,6 +127,16 @@ function maskMobile(mobile?: string | null) {
|
|||||||
|
|
||||||
/** 企业名首字 (Avatar 用) */
|
/** 企业名首字 (Avatar 用) */
|
||||||
function initial(name: string) { return name ? name.charAt(0) : '企' }
|
function initial(name: string) { return name ? name.charAt(0) : '企' }
|
||||||
|
/** 头像背景 (有 logo 用图片, 否则渐变) */
|
||||||
|
function avatarStyle(row: Enterprise, index: number) {
|
||||||
|
return { background: AVATAR_GRADIENTS[index % AVATAR_GRADIENTS.length] }
|
||||||
|
}
|
||||||
|
/** 标签前 2 个 + 剩余计数 */
|
||||||
|
function shownTags(row: Enterprise): { tags: string[]; rest: number } {
|
||||||
|
const raw = row.supplierLabel || ''
|
||||||
|
const tags = String(raw).split(/[,,、;;\s]+/).map((s: string) => s.trim()).filter(Boolean)
|
||||||
|
return { tags: tags.slice(0, 2), rest: Math.max(0, tags.length - 2) }
|
||||||
|
}
|
||||||
|
|
||||||
async function load() {
|
async function load() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
@ -168,7 +195,7 @@ function onReset() {
|
|||||||
}
|
}
|
||||||
function onPageChange(p: number) { page.value = p; load() }
|
function onPageChange(p: number) { page.value = p; load() }
|
||||||
function onLimitChange(l: number) { limit.value = l; page.value = 1; load() }
|
function onLimitChange(l: number) { limit.value = l; page.value = 1; load() }
|
||||||
function onSelectionChange(rows: any[]) { selectedIds.value = rows.map((r: any) => r.id) }
|
function onSelectionChange(rows: any[]) { selectedIds.value = rows.map((r: any) => r.id); selectedRows.value = rows }
|
||||||
|
|
||||||
// ========== 审核交互 (后端 GET /user/enterprise/checkStatus?id=&status=&failReason=, 支持逗号批量) ==========
|
// ========== 审核交互 (后端 GET /user/enterprise/checkStatus?id=&status=&failReason=, 支持逗号批量) ==========
|
||||||
function onAudit(row: Enterprise) {
|
function onAudit(row: Enterprise) {
|
||||||
@ -246,7 +273,6 @@ async function deleteHandle() {
|
|||||||
function exportSupplierDetail() { ElMessage.info('导出待实现') }
|
function exportSupplierDetail() { ElMessage.info('导出待实现') }
|
||||||
|
|
||||||
// ========== 单行操作 ==========
|
// ========== 单行操作 ==========
|
||||||
function showDetail(row: Enterprise) { detailRow.value = row; detailVisible.value = true }
|
|
||||||
function goDetail(row: Enterprise) { router.push(`/user/enterprise/detail/${row.id}`) }
|
function goDetail(row: Enterprise) { router.push(`/user/enterprise/detail/${row.id}`) }
|
||||||
function changeAdminHandle(_row: Enterprise) { ElMessage.info('更换管理员待实现') }
|
function changeAdminHandle(_row: Enterprise) { ElMessage.info('更换管理员待实现') }
|
||||||
|
|
||||||
@ -291,7 +317,7 @@ onMounted(() => load())
|
|||||||
:fields="[
|
:fields="[
|
||||||
{ key: 'enterpriseName', label: '企业名称', type: 'text', placeholder: '企业名称' },
|
{ key: 'enterpriseName', label: '企业名称', type: 'text', placeholder: '企业名称' },
|
||||||
{ key: 'industry', label: '行业类型', type: 'text', placeholder: '行业类型' },
|
{ key: 'industry', label: '行业类型', type: 'text', placeholder: '行业类型' },
|
||||||
{ key: 'supplierLevel', label: '供应商等级', type: 'select', placeholder: '供应商等级',
|
{ key: 'supplierLevel', label: '供应商等级', type: 'select', placeholder: '全部等级',
|
||||||
options: [
|
options: [
|
||||||
{ value: 1, label: '优质供应商' },
|
{ value: 1, label: '优质供应商' },
|
||||||
{ value: 2, label: '钻石供应商' },
|
{ value: 2, label: '钻石供应商' },
|
||||||
@ -299,6 +325,13 @@ onMounted(() => load())
|
|||||||
{ value: 4, label: '银牌供应商' },
|
{ value: 4, label: '银牌供应商' },
|
||||||
{ value: 5, label: '铜牌供应商' }
|
{ value: 5, label: '铜牌供应商' }
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{ key: 'status', label: '审核状态', type: 'select', placeholder: '全部状态',
|
||||||
|
options: [
|
||||||
|
{ value: 1, label: '待审核' },
|
||||||
|
{ value: 2, label: '已认证' },
|
||||||
|
{ value: 3, label: '已驳回' }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]"
|
]"
|
||||||
@search="onSearch"
|
@search="onSearch"
|
||||||
@ -306,26 +339,32 @@ onMounted(() => load())
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="rr-list-card">
|
<div class="rr-list-card">
|
||||||
<!-- 批量操作栏 -->
|
<!-- 批量操作栏 (选中时高亮) -->
|
||||||
<div class="rr-batch-bar">
|
<div class="rr-batch-bar" :class="{ 'has-selection': selectedCount > 0 }">
|
||||||
<el-button size="small" type="success" @click="importHandle">导入</el-button>
|
<span v-if="selectedCount > 0" class="batch-count">
|
||||||
<el-button size="small" type="danger" @click="openBatchAudit">批量审核</el-button>
|
已选 <strong>{{ selectedCount }}</strong> 家企业
|
||||||
<el-button size="small" @click="batchLabelHandle">批量设置标签</el-button>
|
</span>
|
||||||
<el-button size="small" type="warning" @click="batchAssignSalesperson">批量分配业务员</el-button>
|
<span v-else class="batch-hint">勾选企业后可执行批量操作</span>
|
||||||
<el-button size="small" type="danger" @click="deleteHandle">删除</el-button>
|
<span class="batch-actions">
|
||||||
<el-button size="small" type="primary" @click="exportSupplierDetail">导出供应商信息明细</el-button>
|
<el-button size="small" type="primary" @click="openBatchAudit">批量审核</el-button>
|
||||||
|
<el-button size="small" @click="batchLabelHandle">批量设置标签</el-button>
|
||||||
|
<el-button size="small" type="warning" plain @click="batchAssignSalesperson">批量分配业务员</el-button>
|
||||||
|
<el-button size="small" @click="importHandle"><el-icon style="margin-right:4px"><Upload /></el-icon>导入</el-button>
|
||||||
|
<el-button size="small" @click="exportSupplierDetail"><el-icon style="margin-right:4px"><Download /></el-icon>导出明细</el-button>
|
||||||
|
<el-button size="small" type="danger" plain @click="deleteHandle">删除</el-button>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<DataTable
|
<DataTable
|
||||||
:columns="[
|
:columns="[
|
||||||
{ type: 'selection', width: 48, label: '' },
|
{ type: 'selection', width: 48, label: '' },
|
||||||
{ label: '企业名称', minWidth: 220, slot: 'enterpriseName' },
|
{ label: '企业名称', minWidth: 250, slot: 'enterpriseName' },
|
||||||
{ label: '企业管理员/手机号', minWidth: 200, slot: 'adminInfo' },
|
{ label: '企业管理员', minWidth: 170, slot: 'adminInfo' },
|
||||||
{ label: '行业类型/供应商等级', minWidth: 200, slot: 'levelInfo' },
|
{ label: '行业 / 供应商等级', minWidth: 190, slot: 'levelInfo' },
|
||||||
{ prop: 'supplierLabel', label: '标签', width: 120, align: 'center' },
|
{ label: '标签', minWidth: 140, slot: 'supplierLabel' },
|
||||||
{ label: '业务员', minWidth: 160, slot: 'salespersonInfo' },
|
{ label: '业务员', minWidth: 150, slot: 'salespersonInfo' },
|
||||||
{ label: '状态', width: 100, slot: 'status' },
|
{ label: '状态', width: 100, slot: 'status', align: 'center' },
|
||||||
{ label: '入驻时间', width: 110, slot: 'createDate' },
|
{ label: '入驻时间', width: 120, slot: 'createDate' },
|
||||||
{ label: '操作', width: 200, slot: 'action', fixed: 'right', align: 'center' }
|
{ label: '操作', width: 200, slot: 'action', fixed: 'right', align: 'center' }
|
||||||
]"
|
]"
|
||||||
:data="list"
|
:data="list"
|
||||||
@ -341,71 +380,91 @@ onMounted(() => load())
|
|||||||
@limit-change="onLimitChange"
|
@limit-change="onLimitChange"
|
||||||
@selection-change="onSelectionChange"
|
@selection-change="onSelectionChange"
|
||||||
>
|
>
|
||||||
<!-- 企业名称(带头像) -->
|
<!-- 企业名称 (头像 + 名称 + 法人) -->
|
||||||
<template #enterpriseName="{ row, index }">
|
<template #enterpriseName="{ row, index }">
|
||||||
<div style="display:flex;align-items:center;gap:8px">
|
<div class="ent-cell">
|
||||||
<span :style="{ display:'inline-flex',alignItems:'center',justifyContent:'center',
|
<span class="ent-avatar" :style="avatarStyle(row, index)">
|
||||||
width:'32px',height:'32px',borderRadius:'50%',flexShrink:0,fontSize:'14px',fontWeight:500,
|
<el-image v-if="row.enterpriseLogo" :src="row.enterpriseLogo" fit="cover" class="ent-avatar-img" />
|
||||||
background:index%2===0?'#fce4ec':'#e3f2fd',color:index%2===0?'#c62828':'#1565c0'
|
<template v-else>{{ initial(row.enterpriseName) }}</template>
|
||||||
}">{{ initial(row.enterpriseName) }}</span>
|
</span>
|
||||||
<span style="font-weight:500">{{ row.enterpriseName }}</span>
|
<span class="ent-text">
|
||||||
|
<span class="ent-name">{{ row.enterpriseName }}</span>
|
||||||
|
<span class="ent-sub" v-if="row.legalMan && row.legalMan !== '--'">法人:{{ row.legalMan }}</span>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 企业管理员/手机号(两行) -->
|
<!-- 企业管理员/手机号 (两行) -->
|
||||||
<template #adminInfo="{ row }">
|
<template #adminInfo="{ row }">
|
||||||
<div style="display:flex;flex-direction:column;gap:2px">
|
<div class="two-line">
|
||||||
<span>{{ row.administrator }}</span>
|
<span class="line-main">{{ row.administrator }}</span>
|
||||||
<span style="font-size:12px;color:var(--ink-3)">{{ maskMobile(row.administratorMobile) }}</span>
|
<span class="line-sub"><el-icon><User /></el-icon>{{ maskMobile(row.administratorMobile) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 行业类型/供应商等级(两行) -->
|
<!-- 行业/供应商等级 (两行 + 等级徽章) -->
|
||||||
<template #levelInfo="{ row }">
|
<template #levelInfo="{ row }">
|
||||||
<div style="display:flex;flex-direction:column;gap:2px">
|
<div class="two-line">
|
||||||
<span>{{ row.industry || '-' }}</span>
|
<span class="line-main">{{ row.industry || '-' }}</span>
|
||||||
<span style="font-size:12px;color:var(--ink-3)">{{ LEVEL_MAP[row.supplierLevel as number] || '-' }}</span>
|
<span v-if="LEVEL_META[row.supplierLevel as number]" class="level-chip"
|
||||||
|
:style="{ color: LEVEL_META[row.supplierLevel as number].color, background: LEVEL_META[row.supplierLevel as number].bg }">
|
||||||
|
{{ LEVEL_META[row.supplierLevel as number].label }}
|
||||||
|
</span>
|
||||||
|
<span v-else class="line-sub">未评级</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- 标签 (前 2 个 + 溢出) -->
|
||||||
|
<template #supplierLabel="{ row }">
|
||||||
|
<div class="label-tags" v-if="row.supplierLabel">
|
||||||
|
<span v-for="(t, i) in shownTags(row).tags" :key="i" class="label-tag">{{ t }}</span>
|
||||||
|
<span v-if="shownTags(row).rest > 0" class="label-more">+{{ shownTags(row).rest }}</span>
|
||||||
|
</div>
|
||||||
|
<span v-else class="rr-muted">--</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
<!-- 业务员 -->
|
<!-- 业务员 -->
|
||||||
<template #salespersonInfo="{ row }">
|
<template #salespersonInfo="{ row }">
|
||||||
<div v-if="row.salesperson" style="font-size:12px;color:var(--ink-3)">
|
<div v-if="row.salesperson" class="two-line">
|
||||||
{{ row.salesperson }}({{ maskMobile(row.salespersonMobile) }})
|
<span class="line-main">{{ row.salesperson }}</span>
|
||||||
|
<span class="line-sub">{{ maskMobile(row.salespersonMobile) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-else style="font-size:12px;color:var(--ink-3);font-style:italic">暂未分配</div>
|
<span v-else class="unassigned">待分配</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 状态标签 -->
|
<!-- 状态标签 (圆点 + 脉冲待审核) -->
|
||||||
<template #status="{ row }">
|
<template #status="{ row }">
|
||||||
<span v-if="STATUS_MAP[String(row.status)]" :class="['rr-status-tag', STATUS_CLASS[String(row.status)] || '']">
|
<span v-if="STATUS_META[String(row.status)]" class="status-tag" :class="{ pulsing: row.status === 1 }"
|
||||||
{{ STATUS_MAP[String(row.status)] }}
|
:style="{ color: STATUS_META[String(row.status)].color, background: STATUS_META[String(row.status)].bg }">
|
||||||
|
<span class="status-dot"></span>{{ STATUS_META[String(row.status)].label }}
|
||||||
</span>
|
</span>
|
||||||
<span v-else class="rr-muted">--</span>
|
<span v-else class="rr-muted">--</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 入驻时间 -->
|
<!-- 入驻时间 -->
|
||||||
<template #createDate="{ row }">
|
<template #createDate="{ row }">
|
||||||
<span style="font-family:'SF Mono',Menlo,monospace;font-size:12px">{{ fmtDate(row.createDate) }}</span>
|
<span class="date-cell"><el-icon><Clock /></el-icon>{{ fmtDate(row.createDate) }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 操作列 -->
|
<!-- 操作列 -->
|
||||||
<template #action="{ row }">
|
<template #action="{ row }">
|
||||||
<div style="display:flex;align-items:center;gap:2px">
|
<div class="action-cell">
|
||||||
<el-button type="primary" size="small" text @click="goDetail(row)">详情</el-button>
|
<el-button type="primary" size="small" text @click="goDetail(row)">详情</el-button>
|
||||||
<el-button type="primary" size="small" text @click="changeAdminHandle(row)">更换管理员</el-button>
|
<el-button size="small" text @click="changeAdminHandle(row)">更换管理员</el-button>
|
||||||
<el-dropdown trigger="click" placement="bottom-end" @command="(cmd:string) => handleMore(cmd, row)">
|
<el-dropdown trigger="click" placement="bottom-end" @command="(cmd:string) => handleMore(cmd, row)">
|
||||||
<el-button type="primary" size="small" text><el-icon><MoreFilled /></el-icon></el-button>
|
<el-button size="small" text><el-icon><MoreFilled /></el-icon></el-button>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item v-if="row.status===1" command="audit">审核</el-dropdown-item>
|
<el-dropdown-item v-if="row.status===1" command="audit">
|
||||||
|
<span class="dd-audit">审核</span>
|
||||||
|
</el-dropdown-item>
|
||||||
<el-dropdown-item command="label">标签</el-dropdown-item>
|
<el-dropdown-item command="label">标签</el-dropdown-item>
|
||||||
<el-dropdown-item command="rating">评级</el-dropdown-item>
|
<el-dropdown-item command="rating">评级</el-dropdown-item>
|
||||||
<el-dropdown-item command="enabled">{{ row.enabled===1?'启用':'禁用' }}</el-dropdown-item>
|
<el-dropdown-item divided command="enabled">{{ row.enabled===1?'启用':'禁用' }}</el-dropdown-item>
|
||||||
<el-dropdown-item command="showFlag">{{ row.showFlag===1?'显示企业':'隐藏企业' }}</el-dropdown-item>
|
<el-dropdown-item command="showFlag">{{ row.showFlag===1?'显示企业':'隐藏企业' }}</el-dropdown-item>
|
||||||
<el-dropdown-item command="homeShow">{{ row.homeShow===1?'取消推荐':'推荐显示' }}</el-dropdown-item>
|
<el-dropdown-item command="homeShow">{{ row.homeShow===1?'取消推荐':'推荐显示' }}</el-dropdown-item>
|
||||||
<el-dropdown-item command="assign">分配业务员</el-dropdown-item>
|
<el-dropdown-item command="assign">分配业务员</el-dropdown-item>
|
||||||
<el-dropdown-item command="deleteRow">删除</el-dropdown-item>
|
<el-dropdown-item divided command="deleteRow" class="dd-danger">删除</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
@ -414,34 +473,6 @@ onMounted(() => load())
|
|||||||
</DataTable>
|
</DataTable>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 详情弹窗 (EnterpriseDTO 全字段) -->
|
|
||||||
<el-dialog v-model="detailVisible" title="企业详情" width="700px" :close-on-click-modal="false" destroy-on-close>
|
|
||||||
<template v-if="detailRow">
|
|
||||||
<el-descriptions :column="2" border size="small">
|
|
||||||
<el-descriptions-item label="企业名称">{{ detailRow.enterpriseName }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="管理员">{{ detailRow.administrator }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="管理员手机">{{ maskMobile(detailRow.administratorMobile) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="行业">{{ detailRow.industry || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="供应商等级">{{ LEVEL_MAP[detailRow.supplierLevel as number] || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="标签">{{ detailRow.supplierLabel || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="业务员">{{ detailRow.salesperson || '暂未分配' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="状态">{{ STATUS_MAP[String(detailRow.status)] || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item v-if="detailRow.status===3" label="驳回原因" :span="2">{{ detailRow.failReason || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="入驻时间">{{ fmtDate(detailRow.createDate) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="法人代表">{{ detailRow.legalMan }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="联系电话">{{ maskMobile(detailRow.linkMobile) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="邮箱">{{ detailRow.email || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="地址" :span="2">{{ detailRow.enterpriseAddress || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="主营产品" :span="2">{{ detailRow.mainProducts || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="工商号">{{ detailRow.orgNo || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="注册时间">{{ fmtDate(detailRow.registerTime) }}</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
|
||||||
</template>
|
|
||||||
<template #footer>
|
|
||||||
<el-button @click="detailVisible=false">关闭</el-button>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<!-- 单行审核弹窗 -->
|
<!-- 单行审核弹窗 -->
|
||||||
<el-dialog v-model="auditVisible" title="企业认证审核" width="480px" :close-on-click-modal="false" destroy-on-close>
|
<el-dialog v-model="auditVisible" title="企业认证审核" width="480px" :close-on-click-modal="false" destroy-on-close>
|
||||||
<div style="background:var(--bg,#f6f8fb);border:1px solid var(--border);border-radius:8px;padding:10px 14px;font-size:13px;color:var(--ink-2);margin-bottom:18px">
|
<div style="background:var(--bg,#f6f8fb);border:1px solid var(--border);border-radius:8px;padding:10px 14px;font-size:13px;color:var(--ink-2);margin-bottom:18px">
|
||||||
@ -497,15 +528,82 @@ onMounted(() => load())
|
|||||||
.rr-list-card {
|
.rr-list-card {
|
||||||
background: var(--surface); border-radius: 12px; overflow: hidden;
|
background: var(--surface); border-radius: 12px; overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===== 批量操作栏 ===== */
|
||||||
.rr-batch-bar {
|
.rr-batch-bar {
|
||||||
display: flex; gap: 8px; flex-wrap: wrap; padding: 12px 16px;
|
display: flex; align-items: center; gap: 12px; padding: 12px 16px;
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
|
transition: background .2s;
|
||||||
}
|
}
|
||||||
.rr-status-tag {
|
.rr-batch-bar.has-selection { background: var(--primary-soft, #e0ecff); }
|
||||||
display: inline-block; padding: 2px 10px; border-radius: 4px; font-size: 12px; font-weight: 500;
|
.batch-count { font-size: 13px; color: var(--ink-2); }
|
||||||
|
.batch-count strong { color: var(--primary); font-size: 15px; }
|
||||||
|
.batch-hint { font-size: 12px; color: var(--ink-3); }
|
||||||
|
.batch-actions { margin-left: auto; display: flex; gap: 4px; flex-wrap: wrap; }
|
||||||
|
|
||||||
|
/* ===== 企业名称 ===== */
|
||||||
|
.ent-cell { display: flex; align-items: center; gap: 10px; }
|
||||||
|
.ent-avatar {
|
||||||
|
flex: 0 0 38px; width: 38px; height: 38px; border-radius: 10px;
|
||||||
|
display: flex; align-items: center; justify-content: center;
|
||||||
|
color: #fff; font-size: 16px; font-weight: 700; flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.rr-tag-warn { background: #fff3e0; color: #e65100; }
|
.ent-avatar-img { width: 100%; height: 100%; border-radius: 10px; }
|
||||||
.rr-tag-ok { background: #e8f5e9; color: #2e7d32; }
|
.ent-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
|
||||||
.rr-tag-err { background: #fce4ec; color: #c62828; }
|
.ent-name { font-size: 14px; font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||||
|
.ent-sub { font-size: 12px; color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||||
|
|
||||||
|
/* ===== 两行单元格 ===== */
|
||||||
|
.two-line { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
|
||||||
|
.line-main { font-size: 13px; color: var(--ink); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||||
|
.line-sub { display: flex; align-items: center; gap: 4px; font-size: 12px; color: var(--ink-3); }
|
||||||
|
|
||||||
|
/* ===== 等级徽章 ===== */
|
||||||
|
.level-chip {
|
||||||
|
display: inline-flex; align-items: center; width: fit-content;
|
||||||
|
font-size: 11px; font-weight: 600; padding: 2px 10px; border-radius: 20px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== 标签 ===== */
|
||||||
|
.label-tags { display: flex; gap: 6px; flex-wrap: wrap; }
|
||||||
|
.label-tag {
|
||||||
|
font-size: 11px; color: var(--primary); background: var(--primary-soft, #e0ecff);
|
||||||
|
padding: 2px 10px; border-radius: 6px; white-space: nowrap;
|
||||||
|
}
|
||||||
|
.label-more { font-size: 11px; color: var(--ink-3); align-self: center; }
|
||||||
|
|
||||||
|
/* ===== 业务员 ===== */
|
||||||
|
.unassigned {
|
||||||
|
display: inline-flex; font-size: 11px; color: var(--ink-3);
|
||||||
|
background: var(--bg, #f6f8fb); border: 1px dashed var(--border);
|
||||||
|
padding: 2px 10px; border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== 状态标签 ===== */
|
||||||
|
.status-tag {
|
||||||
|
display: inline-flex; align-items: center; gap: 6px;
|
||||||
|
font-size: 12px; font-weight: 500; padding: 3px 12px; border-radius: 20px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.status-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
|
||||||
|
.status-tag.pulsing .status-dot { animation: pulse-dot 1.6s ease-in-out infinite; }
|
||||||
|
@keyframes pulse-dot {
|
||||||
|
0%, 100% { box-shadow: 0 0 0 0 rgba(180, 83, 9, .4); }
|
||||||
|
50% { box-shadow: 0 0 0 5px rgba(180, 83, 9, 0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== 入驻时间 ===== */
|
||||||
|
.date-cell { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--ink-2); font-family: 'SF Mono', Menlo, Consolas, monospace; }
|
||||||
|
|
||||||
|
/* ===== 操作列 ===== */
|
||||||
|
.action-cell { display: flex; align-items: center; gap: 2px; }
|
||||||
|
.dd-audit { color: #b45309; font-weight: 600; }
|
||||||
|
.dd-danger { color: #dc2626; }
|
||||||
|
|
||||||
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
.rr-muted { color: var(--ink-3); font-size: 12px; }
|
||||||
|
|
||||||
|
@media (max-width: 1200px) {
|
||||||
|
.batch-actions { margin-left: 0; }
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
Loading…
Reference in New Issue
Block a user