feat(api)!: 适配新版后端接口
切换到 Cookie 会话和新版 DTO,并迁移画廊、地图、个人主页、百科及上传流程。停用后端尚未实现的账号与徽章功能,同时纳入新版 API 契约文档。 BREAKING CHANGE: 前端不再兼容旧 /api/v1 接口和 refresh token 流程。
This commit is contained in:
@@ -91,9 +91,7 @@ function handleRemove(id: string) {
|
||||
function onCategoryChange(event: Event) {
|
||||
if (!activeItem.value) return
|
||||
const value = (event.target as HTMLSelectElement).value
|
||||
if (value === 'other') {
|
||||
activeItem.value.cloudCategoryId = 'other'
|
||||
} else if (value === '') {
|
||||
if (value === '') {
|
||||
activeItem.value.cloudCategoryId = null
|
||||
} else {
|
||||
activeItem.value.cloudCategoryId = Number(value)
|
||||
@@ -102,6 +100,7 @@ function onCategoryChange(event: Event) {
|
||||
}
|
||||
|
||||
function formatDatetimeLocal(iso: string): string {
|
||||
if (!iso) return ''
|
||||
const date = new Date(iso)
|
||||
const pad = (value: number) => String(value).padStart(2, '0')
|
||||
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}`
|
||||
@@ -110,8 +109,7 @@ function formatDatetimeLocal(iso: string): string {
|
||||
function onCapturedAtChange(event: Event) {
|
||||
if (!activeItem.value) return
|
||||
const value = (event.target as HTMLInputElement).value
|
||||
if (!value) return
|
||||
activeItem.value.capturedAt = new Date(value).toISOString()
|
||||
activeItem.value.capturedAt = value ? new Date(value).toISOString() : ''
|
||||
delete activeItem.value.errors.capturedAt
|
||||
}
|
||||
|
||||
@@ -169,7 +167,7 @@ async function handleSubmit() {
|
||||
|
||||
const result = await uploadAll()
|
||||
if (!result.ok) {
|
||||
errorMsg.value = '上传失败,请稍后重试'
|
||||
errorMsg.value = result.errorMessage || '上传失败,请稍后重试'
|
||||
return
|
||||
}
|
||||
|
||||
@@ -217,7 +215,7 @@ onBeforeUnmount(() => {
|
||||
</div>
|
||||
|
||||
<div class="max-h-[72vh] overflow-y-auto px-5 py-5">
|
||||
<input ref="fileInput" type="file" accept="image/*" class="hidden" @change="handleFileSelect" />
|
||||
<input ref="fileInput" type="file" accept="image/jpeg,image/png,image/webp" class="hidden" @change="handleFileSelect" />
|
||||
|
||||
<NAlert v-if="successMsg" type="success" :bordered="false" title="已提交审核" class="mb-4">
|
||||
图片审核通过后会出现在画廊和地图中。
|
||||
@@ -248,7 +246,7 @@ onBeforeUnmount(() => {
|
||||
>
|
||||
<NIcon size="42" class="text-sky-600"><CloudUpload /></NIcon>
|
||||
<p class="mt-3 text-base font-semibold text-slate-800">选择一张云图</p>
|
||||
<p class="oc-field-help">支持 JPG、PNG,可点击或拖拽上传。</p>
|
||||
<p class="oc-field-help">支持 JPEG、PNG、WebP,图片不超过 20MB。</p>
|
||||
</div>
|
||||
|
||||
<template v-else-if="activeItem">
|
||||
@@ -275,21 +273,13 @@ onBeforeUnmount(() => {
|
||||
<option v-for="cloudType in cloudsStore.cloudTypes" :key="cloudType.id" :value="cloudType.id">
|
||||
{{ cloudType.name }}({{ cloudType.name_en }})
|
||||
</option>
|
||||
<option value="other">其他</option>
|
||||
</select>
|
||||
<input
|
||||
v-if="activeItem.cloudCategoryId === 'other'"
|
||||
v-model="activeItem.customCloudType"
|
||||
type="text"
|
||||
placeholder="输入云的类型"
|
||||
class="oc-field-control mt-2"
|
||||
@input="activeItem.errors = {}"
|
||||
/>
|
||||
<p v-if="activeItem.errors.cloudCategory" class="oc-field-error">{{ activeItem.errors.cloudCategory }}</p>
|
||||
<p v-if="activeItem.errors.file" class="oc-field-error">{{ activeItem.errors.file }}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="oc-field-label">拍摄时间 <span class="oc-field-required">*</span></label>
|
||||
<label class="oc-field-label">拍摄时间</label>
|
||||
<input
|
||||
type="datetime-local"
|
||||
:value="formatDatetimeLocal(activeItem.capturedAt)"
|
||||
@@ -300,7 +290,7 @@ onBeforeUnmount(() => {
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="oc-field-label">经纬度</label>
|
||||
<label class="oc-field-label">经纬度 <span class="oc-field-required">*</span></label>
|
||||
<div class="grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_40px] gap-2">
|
||||
<div>
|
||||
<input
|
||||
@@ -336,17 +326,7 @@ onBeforeUnmount(() => {
|
||||
</NIcon>
|
||||
</button>
|
||||
</div>
|
||||
<p class="mt-1 text-xs text-slate-400">选填,可手动输入,也可以点击右侧地图按钮选点。</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="oc-field-label">位置名称</label>
|
||||
<input
|
||||
v-model="activeItem.locationName"
|
||||
type="text"
|
||||
placeholder="如:北京、成都"
|
||||
class="oc-field-control"
|
||||
/>
|
||||
<p class="mt-1 text-xs text-slate-400">必填,可手动输入,也可以点击右侧地图按钮选点。</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@@ -354,9 +334,11 @@ onBeforeUnmount(() => {
|
||||
<textarea
|
||||
v-model="activeItem.description"
|
||||
rows="3"
|
||||
maxlength="128"
|
||||
placeholder="描述一下这张图片..."
|
||||
class="oc-field-control resize-none"
|
||||
></textarea>
|
||||
<p v-if="activeItem.errors.description" class="oc-field-error">{{ activeItem.errors.description }}</p>
|
||||
</div>
|
||||
|
||||
<label class="flex items-center justify-between gap-4 border border-slate-200 bg-slate-50 px-4 py-3">
|
||||
|
||||
Reference in New Issue
Block a user