refactor(styles): 建立统一的生产级样式体系 (#4)

## 变更内容

- 将全局样式拆分为设计令牌、基础规则和语义组件层
- 集中管理 Naive UI 主题配置
- 迁移页面容器、表单、信息面板和按钮等重复样式
- 增加样式体系文档与自动契约检查

## 验证

- `npm run check:styles`
- `npm run build`Reviewed-on: #4
This commit was merged in pull request #4.
This commit is contained in:
2026-07-23 02:41:04 +08:00
parent 51743645e2
commit 16b3dd4aaa
27 changed files with 828 additions and 480 deletions
+12 -12
View File
@@ -442,7 +442,7 @@ onUnmounted(() => {
<button
type="button"
class="w-10 h-10 rounded-lg shadow-md flex items-center justify-center"
:class="authStore.loading || !authStore.isLoggedIn ? 'cursor-not-allowed bg-slate-100 text-slate-300 shadow-none' : 'bg-white hover:bg-gray-50'"
:class="authStore.loading || !authStore.isLoggedIn ? 'cursor-not-allowed bg-slate-100 text-slate-300 shadow-none' : 'bg-white hover:bg-slate-50'"
:title="authStore.isLoggedIn ? '快速上传图片' : '请先登录后上传图片'"
aria-label="快速上传图片"
:disabled="authStore.loading || !authStore.isLoggedIn"
@@ -452,14 +452,14 @@ onUnmounted(() => {
<CloudUpload />
</NIcon>
</button>
<button @click="refresh" class="w-10 h-10 bg-white rounded-lg shadow-md flex items-center justify-center hover:bg-gray-50" title="刷新">
<button @click="refresh" class="oc-map-button" title="刷新">
<span class="text-lg">
<NIcon>
<Refresh/>
</NIcon>
</span>
</button>
<button @click="toggleSat" class="w-10 h-10 bg-white rounded-lg shadow-md flex items-center justify-center hover:bg-gray-50" :title="satelliteOn ? '切换普通视图' : '切换卫星视图'">
<button @click="toggleSat" class="oc-map-button" :title="satelliteOn ? '切换普通视图' : '切换卫星视图'">
<NIcon size="20" style="display: inline-flex; vertical-align: middle;">
<Map v-if="satelliteOn" />
<Satellite v-else />
@@ -467,7 +467,7 @@ onUnmounted(() => {
</button>
<button
type="button"
class="w-10 h-10 bg-white rounded-lg shadow-md flex items-center justify-center hover:bg-gray-50"
class="oc-map-button"
:title="timelineControlsOpen ? '收起时间控件' : '展开时间控件'"
:aria-label="timelineControlsOpen ? '收起时间控件' : '展开时间控件'"
@click="toggleTimelineControls"
@@ -519,7 +519,7 @@ onUnmounted(() => {
<div class="relative">
<button
type="button"
class="w-10 h-10 bg-white rounded-lg shadow-md flex items-center justify-center hover:bg-gray-50"
class="oc-map-button"
title="按日期或月份查看"
aria-label="按日期或月份查看"
@click="archivePanelOpen = !archivePanelOpen"
@@ -562,13 +562,13 @@ onUnmounted(() => {
v-if="archiveKind === 'day'"
v-model="archiveDay"
type="date"
class="mt-3 w-full border border-slate-300 px-3 py-2 text-sm text-slate-800 outline-none focus:border-sky-500 focus:ring-2 focus:ring-sky-100"
class="oc-field-control mt-3"
/>
<input
v-else
v-model="archiveMonth"
type="month"
class="mt-3 w-full border border-slate-300 px-3 py-2 text-sm text-slate-800 outline-none focus:border-sky-500 focus:ring-2 focus:ring-sky-100"
class="oc-field-control mt-3"
/>
<button
@@ -599,19 +599,19 @@ onUnmounted(() => {
>
<div class="grid gap-4 sm:grid-cols-2">
<div class="rounded-2xl bg-slate-50 p-4">
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">上传时间</p>
<p class="oc-section-label">上传时间</p>
<p class="mt-2 text-sm font-medium text-slate-900">{{ formatDateTime(previewCloud.createdAt) }}</p>
</div>
<div class="rounded-2xl bg-slate-50 p-4">
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">拍摄时间</p>
<p class="oc-section-label">拍摄时间</p>
<p class="mt-2 text-sm font-medium text-slate-900">{{ formatDateTime(previewCloud.capturedAt) }}</p>
</div>
<div class="rounded-2xl bg-slate-50 p-4">
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">位置</p>
<p class="oc-section-label">位置</p>
<p class="mt-2 text-sm font-medium text-slate-900">{{ previewCloud.locationName || '未填写位置名称' }}</p>
</div>
<div class="rounded-2xl bg-slate-50 p-4">
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">模糊化经纬度</p>
<p class="oc-section-label">模糊化经纬度</p>
<p class="mt-2 text-sm font-medium text-slate-900">
纬度 {{ formatCoordinate(previewCloud.latitude) }} / 经度 {{ formatCoordinate(previewCloud.longitude) }}
</p>
@@ -619,7 +619,7 @@ onUnmounted(() => {
</div>
<div class="mt-5 rounded-[28px] border border-slate-200 bg-white p-5">
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">图片说明</p>
<p class="oc-section-label">图片说明</p>
<p class="mt-3 text-sm leading-7 text-slate-700">
{{ previewCloud.description || '上传者没有留下额外说明。' }}
</p>