feat ui设计稿bug修复
This commit is contained in:
@@ -6,13 +6,19 @@ import { useHomeStore } from '@/stores/modules/home'
|
||||
import type { PortalEntryCard } from '@/types/business/home'
|
||||
import { toPortalEntryCards } from '@/utils/entryIcon'
|
||||
import HomeAppDialog from './HomeAppDialog.vue'
|
||||
import tileDemand from '@/assets/home/entry-demand.png'
|
||||
import tileCases from '@/assets/home/entry-cases.png'
|
||||
import tileService from '@/assets/home/entry-service.png'
|
||||
import tileContract from '@/assets/home/entry-contract.png'
|
||||
import tileFinance from '@/assets/home/entry-finance.png'
|
||||
|
||||
/**
|
||||
* 首页「快捷入口」卡片。
|
||||
* 首页右上「业务服务」入口卡(设计稿标题即「业务服务」,与下方栏位同名)。
|
||||
*
|
||||
* 数据来自 store.quickEntries(← /vermins/portalEntryUser/list 的 groupType=1 项),
|
||||
* 接口不可用(游客 / 无权限)时回退到内置默认入口,保证卡片不空。
|
||||
* 「更多应用」打开 HomeAppDialog,可在快捷 / 其他两组之间调整入口。
|
||||
* 设计稿固定五个入口,接口返回的多余项(如硬件 / 互联 / 其他)不展示。
|
||||
* 「>>」双箭头打开 HomeAppDialog,可在快捷 / 其他两组之间调整入口。
|
||||
*/
|
||||
const homeStore = useHomeStore()
|
||||
const { quickEntries } = storeToRefs(homeStore)
|
||||
@@ -20,24 +26,42 @@ const router = useRouter()
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
|
||||
/** 接口不可用时的默认入口(与改造前的静态入口保持一致) */
|
||||
/** 设计稿固定入口名目(设计稿没有的接口入口不展示) */
|
||||
const DESIGN_NAMES = ['工单需求池', '案例库管理', '客服工作台', '合同台账', '财务台账']
|
||||
|
||||
/** 接口不可用时的默认入口(与设计稿五项一致,tone 对应设计稿五色) */
|
||||
const FALLBACK_QUICK: PortalEntryCard[] = [
|
||||
{ id: 0, label: '财务台账', route: '/finance/bills', groupType: '1', icon: '💰', isImage: false, tone: 'amber' },
|
||||
{ id: 0, label: '合同台账', route: '/contract', groupType: '1', icon: '📄', isImage: false, tone: 'blue' },
|
||||
{ id: 0, label: '客服工作台', route: '/service', groupType: '1', icon: '💬', isImage: false, tone: 'green' },
|
||||
{ id: 0, label: '案例库管理', route: '/cases', groupType: '1', icon: '📁', isImage: false, tone: 'purple' },
|
||||
{ id: 0, label: '工单需求池', route: '/demand', groupType: '1', icon: '📋', isImage: false, tone: 'cyan' },
|
||||
{ id: 0, label: '工单需求池', route: '/demand', groupType: '1', icon: '', isImage: false, tone: 'cyan' },
|
||||
{ id: 0, label: '案例库管理', route: '/cases', groupType: '1', icon: '', isImage: false, tone: 'purple' },
|
||||
{ id: 0, label: '客服工作台', route: '/service', groupType: '1', icon: '', isImage: false, tone: 'green' },
|
||||
{ id: 0, label: '合同台账', route: '/contract', groupType: '1', icon: '', isImage: false, tone: 'blue' },
|
||||
{ id: 0, label: '财务台账', route: '/finance/bills', groupType: '1', icon: '', isImage: false, tone: 'amber' },
|
||||
]
|
||||
|
||||
/** 设计稿切图:蓝湖整稿 97×97 方块(含底色与白色图案),按入口名映射 */
|
||||
const DESIGN_TILES: Record<string, string> = {
|
||||
工单需求池: tileDemand,
|
||||
案例库管理: tileCases,
|
||||
客服工作台: tileService,
|
||||
合同台账: tileContract,
|
||||
财务台账: tileFinance,
|
||||
}
|
||||
|
||||
/** 前端已注册的静态路由(route 无效时不跳转,避免出现无匹配路由) */
|
||||
const knownPaths = new Set(router.getRoutes().map((item) => item.path))
|
||||
|
||||
/** 卡片展示的入口(最多 5 个) */
|
||||
/** 卡片展示的入口:接口数据按设计稿名目过滤,最多 5 个 */
|
||||
const entries = computed<PortalEntryCard[]>(() => {
|
||||
const list = toPortalEntryCards(quickEntries.value)
|
||||
.filter((card) => DESIGN_NAMES.includes(card.label))
|
||||
return (list.length > 0 ? list : FALLBACK_QUICK).slice(0, 5)
|
||||
})
|
||||
|
||||
/** 入口图:接口 iconUrl 图案优先,否则设计稿切图 */
|
||||
function tileSrc(card: PortalEntryCard): string {
|
||||
return card.isImage && card.icon ? card.icon : (DESIGN_TILES[card.label] ?? '')
|
||||
}
|
||||
|
||||
/** 解析可跳转路径:优先后端 route,其次同名默认入口,最后回首页 */
|
||||
function resolvePath(card: PortalEntryCard): string {
|
||||
if (card.route && knownPaths.has(card.route)) return card.route
|
||||
@@ -56,9 +80,8 @@ function onMore(): void {
|
||||
<template>
|
||||
<section class="home-quick">
|
||||
<div class="home-quick__head">
|
||||
<span class="home-quick__head-icon">⊞</span>
|
||||
<h3 class="home-quick__title">
|
||||
快捷入口
|
||||
业务服务
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
@@ -69,17 +92,19 @@ function onMore(): void {
|
||||
:to="resolvePath(entry)"
|
||||
class="home-quick__item"
|
||||
>
|
||||
<span class="home-quick__icon" :class="`home-quick__icon--${entry.tone}`">
|
||||
<img v-if="entry.isImage" :src="entry.icon" :alt="entry.label" class="home-quick__img">
|
||||
<template v-else>{{ entry.icon }}</template>
|
||||
</span>
|
||||
<!-- 设计稿:97×97 彩色方块 + 白色图案(蓝湖整稿切图),接口 iconUrl 图案优先 -->
|
||||
<img class="home-quick__tile" :src="tileSrc(entry)" :alt="entry.label">
|
||||
<span class="home-quick__label">{{ entry.label }}</span>
|
||||
</RouterLink>
|
||||
</div>
|
||||
|
||||
<button class="home-quick__more link" type="button" @click="onMore">
|
||||
更多应用 >
|
||||
</button>
|
||||
<!-- 设计稿:双箭头图标与入口方块行垂直居中(@y875, 32×32,距末位方块 20) -->
|
||||
<button class="home-quick__more" type="button" aria-label="更多应用" @click="onMore">
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8 6 L18 16 L8 26" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round" fill="none" />
|
||||
<path d="M17 6 L27 16 L17 26" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round" fill="none" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<HomeAppDialog v-model:visible="dialogVisible" />
|
||||
</section>
|
||||
@@ -90,36 +115,35 @@ function onMore(): void {
|
||||
position: relative;
|
||||
.flex(column, flex-start, stretch);
|
||||
flex-shrink: 0;
|
||||
// 设计稿右卡 722×245 设计px → 556 宽;白底 + 浅灰描边
|
||||
width: 556px;
|
||||
// 设计稿右卡 722 宽;白底 + 浅灰描边
|
||||
// flex-basis 代替定宽:窄视口允许收缩,避免横向滚动条(1920 下仍为 722)
|
||||
flex: 0 1 722px;
|
||||
min-width: 0;
|
||||
gap: 0;
|
||||
padding: 14px 31px 21px;
|
||||
// 设计稿:标题盒顶 y772 = 卡顶 +18,方块行顶 y841 = +87,卡高 264
|
||||
padding: 18px 40px 28px;
|
||||
border: 1px solid @home-card-border;
|
||||
border-radius: @radius-lg;
|
||||
background: @white;
|
||||
|
||||
&__head {
|
||||
.flex(row, flex-start);
|
||||
gap: @spacing-sm;
|
||||
}
|
||||
|
||||
&__head-icon {
|
||||
color: @home-ink;
|
||||
font-size: @font-size-xl;
|
||||
}
|
||||
|
||||
&__title {
|
||||
// 设计稿卡内标题 36 设计px / 700 / #121212
|
||||
// 设计稿卡内标题 36px / 700 / #121212,盒高 52(y772-824)
|
||||
font-size: @font-size-xxl;
|
||||
font-weight: 700;
|
||||
line-height: 52px;
|
||||
color: @home-ink;
|
||||
}
|
||||
|
||||
&__list {
|
||||
.flex(row, flex-start, flex-start);
|
||||
// 设计稿入口间距 127 设计px(图标 90 + 间隙 37)≈ 70 + 28
|
||||
gap: 28px;
|
||||
margin-top: 16px;
|
||||
// 设计稿入口图标间距(图标 97 + 间隙 30);方块行顶 y841 = 卡顶 +87
|
||||
gap: 30px;
|
||||
margin-top: 17px;
|
||||
flex-wrap: wrap; // 卡片被收缩时换行,避免卡内溢出
|
||||
}
|
||||
|
||||
&__item {
|
||||
@@ -133,66 +157,41 @@ function onMore(): void {
|
||||
}
|
||||
}
|
||||
|
||||
&__icon {
|
||||
.flex(row, center);
|
||||
// 设计稿图标块 90×90 设计px ≈ 70 CSS
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
// 设计稿:97×97 彩色方块切图(含底色与白色图案),整图渲染
|
||||
&__tile {
|
||||
display: block;
|
||||
width: 97px;
|
||||
height: 97px;
|
||||
border-radius: @radius-base;
|
||||
font-size: 28px;
|
||||
|
||||
// 底色按设计稿采样(tone → 设计稿色)
|
||||
&--amber {
|
||||
background: @home-quick-pink;
|
||||
}
|
||||
|
||||
&--blue {
|
||||
background: @home-quick-peach;
|
||||
}
|
||||
|
||||
&--green {
|
||||
background: @home-quick-green;
|
||||
}
|
||||
|
||||
&--purple {
|
||||
background: @home-quick-purple;
|
||||
}
|
||||
|
||||
&--red {
|
||||
background: fade(@danger-color, 15%);
|
||||
}
|
||||
|
||||
&--cyan {
|
||||
background: @home-quick-blue;
|
||||
}
|
||||
}
|
||||
|
||||
&__img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
object-fit: contain;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
&__label {
|
||||
// 设计稿入口文字 18 设计px / 500 / #121212
|
||||
font-size: @font-size-base;
|
||||
// 设计稿入口文字 18px / 500 / #121212
|
||||
font-size: @font-size-lg;
|
||||
font-weight: 500;
|
||||
color: @home-ink;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&__more {
|
||||
// 设计稿「更多」箭头位于卡片右侧垂直居中
|
||||
// 设计稿:» 32×32 @卡内 (665,121),与方块行(顶 y+87,高 97)垂直居中 → top 87+48.5-16 = 119.5
|
||||
// 绝对定位脱离 flex 流:卡收缩(窄视口)时不参与折行
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 31px;
|
||||
top: 120px;
|
||||
right: 25px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
transform: translateY(-50%);
|
||||
background: transparent;
|
||||
font-size: @font-size-sm;
|
||||
color: @home-ring;
|
||||
color: #c9cdd4;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s;
|
||||
|
||||
&:hover {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user