feat 完善注释

This commit is contained in:
Ironsp
2026-10-01 17:24:57 +08:00
parent 2b59f68fd7
commit 9f4a5c7cda
183 changed files with 485 additions and 3615 deletions

View File

@@ -13,12 +13,10 @@ const emit = defineEmits<{
share: [id: string]
}>()
/** 空值兜底(后端 customerType / industry 等可能不下发) */
function dash(value: string): string {
return value || '--'
}
/** 概览信息(设计稿:标签 + 全角冒号 + 值,单行铺开) */
const meta = computed(() => [
{ label: '客户类型', value: dash(props.item.clientType) },
{ label: '所属行业', value: dash(props.item.industry) },
@@ -126,7 +124,6 @@ const meta = computed(() => [
}
&__meta {
// 显式 stretch:否则元信息行会被居中收缩(设计稿为左起铺满整行)
.flex(column, flex-start, stretch);
flex: 1;
gap: @spacing-sm;

View File

@@ -9,22 +9,14 @@ interface Props {
const props = defineProps<Props>()
/** 业务类型标签(设计稿:蓝色实心胶囊 + 白字) */
const tag = computed(() => formatBusinessType(props.item.category))
/**
* 封面图。
*
* <p>toCase 已把「非可访问地址」收口成空串,无封面时回退主题色底,
* 避免裂图或空白块。</p>
*/
const coverStyle = computed(() =>
props.item.cover ? { backgroundImage: `url(${props.item.cover})` } : undefined,
)
</script>
<template>
<!-- 设计稿:封面通栏(不随内容容器收窄、无圆角),左下叠类型标签 + 案例名 -->
<section class="case-hero" :style="coverStyle">
<div class="container case-hero__inner">
<span v-if="tag" class="case-hero__tag">{{ tag }}</span>
@@ -49,7 +41,6 @@ const coverStyle = computed(() =>
content: '';
position: absolute;
inset: 0;
// 底部压暗,保证白字可读
background: linear-gradient(180deg, rgba(15, 23, 42, 0) 42%, rgba(15, 23, 42, 0.55));
}
@@ -76,7 +67,6 @@ const coverStyle = computed(() =>
font-size: @font-size-xxl;
font-weight: 600;
text-shadow: 0 1px 8px rgba(0, 0, 0, 0.35);
// 最多两行,避免超长案例名撑破 hero
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;

View File

@@ -7,13 +7,6 @@ interface Props {
const props = defineProps<Props>()
/**
* 案例正文区块(设计稿:一段一张白卡,卡片标题带蓝色竖条)。
*
* <p>区块的**数量与标题都来自后端**(vm_project_case_catalog:title + content,
* 按 sort_order 升序),前端不再写死「项目背景 / 客户痛点 / 需求描述 / 交付物」,
* 后端增删目录即自动生效。空内容已在 utils/caseVo.ts#toSections 里过滤。</p>
*/
</script>
<template>
@@ -26,7 +19,6 @@ const props = defineProps<Props>()
<h3 v-if="section.title" class="case-rich__title">
{{ section.title }}
</h3>
<!-- 后端下发富文本 HTML(可能内嵌 img / video),直接渲染 -->
<div class="case-rich__html" v-html="section.content" />
</section>
</div>
@@ -34,7 +26,6 @@ const props = defineProps<Props>()
<style lang="less" scoped>
.case-rich {
// 同 detail.vue:显式 stretch,避免正文块被压成内容宽
.flex(column, flex-start, stretch);
gap: @spacing-base;
@@ -70,8 +61,6 @@ const props = defineProps<Props>()
:deep(p) {
margin-bottom: @spacing-sm;
// 后端富文本常把「1、…2、…」分条内容放在同一个 <p> 里用 \r\n 分行,
// 默认会被 HTML 折叠成一段,故保留换行(与旧纯文本分支的 pre-wrap 行为一致)
white-space: pre-wrap;
}

View File

@@ -7,15 +7,10 @@ import type { BusinessIndustryOption, CaseQuery, CaseTypeOption, ScaleLimit } fr
interface Props {
query: CaseQuery
/** 业务类型选项(接口下发:/categories 的统计;value=提报 id,label=类型名) */
typeOptions: CaseTypeOption[]
/** 所属行业选项(接口下发:/categories) */
industryOptions: BusinessIndustryOption[]
/** 项目规模选项(接口下发:/categories,label 已由后端拼好) */
scaleOptions: ScaleLimit[]
/** 案例总数(全量口径,用于业务类型「全部」行角标) */
caseTotal: number
/** 待提交条件的结果数(「确定筛选(N 个结果)」) */
previewTotal: number
}
@@ -29,7 +24,6 @@ const emit = defineEmits<{
type TimeShortcut = 'all' | '3m' | '6m' | '1y' | 'custom'
/** 完成时间后端未下发选项,保留前端快捷区间 */
const timeShortcuts: Array<{ label: string; value: Exclude<TimeShortcut, 'custom'>; months: number }> = [
{ label: '全部', value: 'all', months: 0 },
{ label: '近3个月', value: '3m', months: 3 },
@@ -37,12 +31,6 @@ const timeShortcuts: Array<{ label: string; value: Exclude<TimeShortcut, 'custom
{ label: '近一年', value: '1y', months: 12 },
]
/**
* 规模档位的稳定标识。
*
* <p>后端档位是「上下限」对象(label 只是展示文字),用上下限拼 key 比 label 可靠:
* 区间值唯一、且不依赖后端文案。</p>
*/
function scaleKey(item: ScaleLimit): string {
return `${item.lowerLimit ?? ''}-${item.upperLimit ?? ''}`
}
@@ -51,7 +39,6 @@ function scaleLabel(item: ScaleLimit): string {
return item.label ?? `${item.lowerLimit ?? 0}-${item.upperLimit ?? '不限'}万`
}
/** 快捷区间 → 具体日期区间 */
function rangeOf(months: number): [string, string] {
const end = new Date()
const start = new Date()
@@ -59,7 +46,6 @@ function rangeOf(months: number): [string, string] {
return [formatDate(start, 'YYYY-MM-DD'), formatDate(end, 'YYYY-MM-DD')]
}
/** 当前区间命中的快捷项(用于选中态回显,避免额外维护一份状态) */
const activeShortcut = computed<TimeShortcut>(() => {
const range = props.query.dateRange
if (!range) return 'all'
@@ -160,7 +146,6 @@ function clearChips(): void {
</button>
</div>
<!-- 业务类型(接口下发;带案例数) -->
<section class="case-filter__group">
<h3 class="case-filter__group-title">
业务类型
@@ -191,7 +176,6 @@ function clearChips(): void {
</ul>
</section>
<!-- 所属行业(接口下发,多选) -->
<section class="case-filter__group">
<h3 class="case-filter__group-title">
所属行业
@@ -216,7 +200,6 @@ function clearChips(): void {
</div>
</section>
<!-- 项目规模(接口下发,多选) -->
<section class="case-filter__group">
<h3 class="case-filter__group-title">
项目规模
@@ -241,7 +224,6 @@ function clearChips(): void {
</div>
</section>
<!-- 完成时间(快捷区间 + 自定义;后端未下发该组选项) -->
<section class="case-filter__group">
<h3 class="case-filter__group-title">
完成时间
@@ -271,7 +253,6 @@ function clearChips(): void {
</div>
</section>
<!-- 已选条件 -->
<section class="case-filter__selected">
<div class="case-filter__selected-head">
<span class="case-filter__selected-title">已选条件({{ chips.length }}个)</span>
@@ -309,7 +290,6 @@ function clearChips(): void {
<style lang="less" scoped>
.case-filter {
flex-shrink: 0;
// 设计稿筛选面板 矩形 148286 @(70,272) 516×1461 白底
width: 516px;
padding: 15px 0 40px;
border-radius: @radius-base;
@@ -318,7 +298,6 @@ function clearChips(): void {
&__head,
&__group,
&__actions {
// 设计稿内容左 x105 → 卡内 x35;行右 x536 → 卡内右 50
padding: 0 50px 0 35px;
}
@@ -327,7 +306,6 @@ function clearChips(): void {
}
&__title {
// 设计 @(105,287) 28/500 #222222
font-size: 28px;
font-weight: 500;
line-height: 41px;
@@ -347,20 +325,17 @@ function clearChips(): void {
margin-top: 24px;
}
// 标题 → 第一组(设计 287+41=328 → 业务类型标题 339)
&__head + &__group {
margin-top: 11px;
}
&__group-title {
// 设计 @(105,339) 24/500 #333333
font-size: 24px;
font-weight: 500;
line-height: 35px;
color: @cases-text;
}
/* 业务类型:整行可点(设计行高 50,文案 20/400) */
&__rows {
margin-top: 19px;
}
@@ -419,7 +394,6 @@ function clearChips(): void {
}
&__row-count {
// 设计计数 16/500 #666666
color: @cases-muted;
font-size: 16px;
font-weight: 500;
@@ -430,7 +404,6 @@ function clearChips(): void {
font-weight: inherit;
}
/* 胶囊选项(两列;设计胶囊高 53、行距 24、列距 33) */
&__pills {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
@@ -506,7 +479,6 @@ function clearChips(): void {
}
}
/* 已选条件 */
&__selected {
margin: 23px 50px 0 35px;
padding: 16px 24px 21px;
@@ -552,7 +524,6 @@ function clearChips(): void {
}
}
/* 底部操作 */
&__actions {
.flex(row, flex-start, center);
gap: 13px;

View File

@@ -4,7 +4,6 @@ import type { Case } from '@/types/business/cases'
interface Props {
cases: Case[]
/** 当前筛选条件下的案例总数 */
total: number
}
@@ -41,13 +40,11 @@ const emit = defineEmits<{
<style lang="less" scoped>
.cases-grid {
&__total {
// 设计计数 20px / 700 / #121212
font-size: 20px;
font-weight: 700;
color: @heading-color;
}
// 设计卡片 396×267,列 x606/1030/1454 → 列距 28,行 y423/713 → 行距 23
&__list {
display: grid;
grid-template-columns: repeat(3, 1fr);

View File

@@ -3,7 +3,6 @@ import { computed } from 'vue'
interface Props {
keyword: string
/** 是否只看收藏 */
favoriteOnly: boolean
}
@@ -60,7 +59,6 @@ const keyword = computed<string>({
<style lang="less" scoped>
.case-search {
.flex(row, flex-start, center);
// 设计稿搜索卡 矩形 148317 @(606,272) 1244×128;输入框 @(642,312) 592×49
gap: 24px;
height: 128px;
box-sizing: border-box;
@@ -70,7 +68,6 @@ const keyword = computed<string>({
&__field {
position: relative;
// 设计输入框 592 宽
flex: 0 0 592px;
}
@@ -100,7 +97,6 @@ const keyword = computed<string>({
transition: border-color 0.2s;
&::placeholder {
// 设计 placeholder @(660,322) 20/400 #999999
color: @text-color-disabled;
}
@@ -110,7 +106,6 @@ const keyword = computed<string>({
}
&__btn {
// 设计按钮文字 20/400 #FFFFFF,白底蓝字按钮宽 100
min-width: 100px;
height: 49px;
padding: 0 @spacing-base;