refactor(ECR-001): 接入 ESS 并完成结构对齐 Phase A–E
绑定 ESS 双轨治理,拆分超大 H5 页与 Go 引擎,抽出 membership 服务, 并将 star/fortune 重命名为 outlook(JSON 双写兼容);同时修复 /psy API 代理与首页 + 菜单层级。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,215 @@
|
||||
<template>
|
||||
<section class="self-card reveal" style="--d: 80ms" @click="$emit('open-portrait')">
|
||||
<div class="self-head">
|
||||
<button type="button" class="who-btn" @click.stop="$emit('open-profile')">
|
||||
{{ profileLabel }}
|
||||
<span class="caret" aria-hidden="true">▾</span>
|
||||
</button>
|
||||
<router-link class="more" to="/profile" @click.stop>更多</router-link>
|
||||
</div>
|
||||
|
||||
<div class="self-body">
|
||||
<div class="mood-col">
|
||||
<div class="mood-label">
|
||||
今日心情 <em>{{ mood.score }}</em><span>分</span>
|
||||
</div>
|
||||
<p class="mood-text">{{ mood.text }}</p>
|
||||
</div>
|
||||
<div class="dims" role="list">
|
||||
<div
|
||||
v-for="d in mood.dims"
|
||||
:key="d.key"
|
||||
class="dim"
|
||||
role="listitem"
|
||||
:style="{ '--bar': d.color, '--h': d.score + '%' }"
|
||||
>
|
||||
<b class="dim-score">{{ d.score }}</b>
|
||||
<div class="dim-track">
|
||||
<i class="dim-fill" />
|
||||
</div>
|
||||
<span class="dim-label">{{ d.label }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
profileLabel: string
|
||||
mood: {
|
||||
score: number
|
||||
text: string
|
||||
dims: { key: string; label: string; score: number; color: string }[]
|
||||
}
|
||||
}>()
|
||||
|
||||
defineEmits<{
|
||||
'open-portrait': []
|
||||
'open-profile': []
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.self-card {
|
||||
margin: 12px 16px 0;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
padding: 14px 14px 16px;
|
||||
background: var(--color-surface);
|
||||
border-radius: var(--radius-xl);
|
||||
box-shadow: var(--shadow-hero);
|
||||
transition: transform var(--duration-fast) ease;
|
||||
}
|
||||
.self-card:active {
|
||||
transform: scale(0.99);
|
||||
}
|
||||
.self-head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.who-btn {
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: var(--color-text-primary);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 0;
|
||||
font-family: var(--font-sans);
|
||||
}
|
||||
.caret {
|
||||
font-size: 10px;
|
||||
color: var(--color-text-tertiary);
|
||||
}
|
||||
.self-head .more {
|
||||
font-size: 12px;
|
||||
color: var(--color-text-tertiary);
|
||||
}
|
||||
.self-head .more::after {
|
||||
content: ' ›';
|
||||
}
|
||||
.self-body {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: stretch;
|
||||
}
|
||||
.mood-col {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding-right: 4px;
|
||||
}
|
||||
.mood-label {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--color-text-primary);
|
||||
line-height: 1.2;
|
||||
}
|
||||
.mood-label em {
|
||||
font-style: normal;
|
||||
font-family: var(--font-display);
|
||||
font-size: 34px;
|
||||
font-weight: 700;
|
||||
color: var(--color-primary);
|
||||
margin: 0 1px 0 4px;
|
||||
letter-spacing: -0.02em;
|
||||
vertical-align: -4px;
|
||||
}
|
||||
.mood-label span {
|
||||
font-size: 12px;
|
||||
color: var(--color-text-tertiary);
|
||||
font-weight: 500;
|
||||
}
|
||||
.mood-text {
|
||||
margin-top: 8px;
|
||||
font-size: 12px;
|
||||
color: #777;
|
||||
line-height: 1.55;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
.dims {
|
||||
display: flex;
|
||||
gap: 7px;
|
||||
align-items: flex-end;
|
||||
flex-shrink: 0;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
.dim {
|
||||
width: 28px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
.dim-score {
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
color: var(--color-text-primary);
|
||||
line-height: 1;
|
||||
}
|
||||
.dim-track {
|
||||
width: 12px;
|
||||
height: 64px;
|
||||
border-radius: var(--radius-pill);
|
||||
background: #f3ece8;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
.dim-fill {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: var(--h);
|
||||
border-radius: var(--radius-pill);
|
||||
background: linear-gradient(180deg, color-mix(in srgb, var(--bar) 70%, #fff) 0%, var(--bar) 100%);
|
||||
box-shadow: 0 -1px 0 rgba(255, 255, 255, 0.35) inset;
|
||||
animation: fillUp 0.7s cubic-bezier(0.22, 1, 0.36, 1) both;
|
||||
animation-delay: calc(var(--d, 80ms) + 120ms);
|
||||
}
|
||||
@keyframes fillUp {
|
||||
from {
|
||||
height: 0;
|
||||
}
|
||||
to {
|
||||
height: var(--h);
|
||||
}
|
||||
}
|
||||
.dim-label {
|
||||
font-size: 10px;
|
||||
color: var(--color-text-secondary);
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.reveal {
|
||||
animation: rise 0.45s cubic-bezier(0.22, 1, 0.36, 1) both;
|
||||
animation-delay: var(--d, 0ms);
|
||||
}
|
||||
@keyframes rise {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.reveal,
|
||||
.dim-fill {
|
||||
animation: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user