完成80%

This commit is contained in:
2026-07-27 06:50:07 +08:00
parent 8475bbd19a
commit 1eae3bbef4
63 changed files with 13664 additions and 280 deletions
+21 -6
View File
@@ -27,9 +27,17 @@
<text class="media-field__label">拍摄人</text>
<input v-model="form.photographer" maxlength="30" placeholder="请输入拍摄人" placeholder-class="placeholder" @input="submitError = ''" />
</view>
<view class="media-field">
<view class="media-field media-field--picker">
<text class="media-field__label">拍摄日期</text>
<picker mode="date" :value="form.shootDate" @change="selectShootDate">
<view :class="{ placeholder: !form.shootDate }">{{ form.shootDate || '请选择' }}</view>
</picker>
</view>
<view class="media-field media-field--picker">
<text class="media-field__label">拍摄时间</text>
<input v-model="form.shootTime" maxlength="30" placeholder="例如:2026-07-24 10:00:00" placeholder-class="placeholder" @input="submitError = ''" />
<picker mode="time" :value="form.shootClock" @change="selectShootClock">
<view :class="{ placeholder: !form.shootClock }">{{ form.shootClock || '请选择' }}</view>
</picker>
</view>
<view class="media-field">
<text class="media-field__label">排序值</text>
@@ -79,13 +87,14 @@ const uploadError = ref("");
const submitError = ref("");
const uploading = ref(false);
const submitting = ref(false);
const form = reactive({ photoTitle: "", photoDesc: "", photographer: "", shootTime: "", sortOrder: "" });
const form = reactive({ photoTitle: "", photoDesc: "", photographer: "", shootDate: "", shootClock: "", sortOrder: "" });
const controller = createRequestController();
const discardVisible = ref(false);
const confirmation = createDiscardConfirmation((visible) => { discardVisible.value = visible; });
const hasValidContext = computed(() => /^[1-9]\d*$/.test(genealogyId.value) && /^[1-9]\d*$/.test(albumId.value));
const isDirty = computed(() => receipt.value || Object.values(form).some((value) => value.trim()));
const isDirty = computed(() => Boolean(receipt.value) || Object.values(form).some((value) => value.trim()));
const shootTime = computed(() => form.shootDate ? `${form.shootDate} ${form.shootClock || "00:00"}:00` : "");
const stateCopy = computed(() => pageState.value === "success"
? { title: "照片已提交服务端", copy: "服务端已返回成功结果。", action: "返回相册" }
: { title: "照片入口无效", copy: "没有取得有效家谱或相册标识。", action: "返回上一页" });
@@ -110,6 +119,8 @@ const selectPhoto = async () => {
uploading.value = false;
}
};
const selectShootDate = (event) => { form.shootDate = event.detail.value || ""; submitError.value = ""; };
const selectShootClock = (event) => { form.shootClock = event.detail.value || ""; submitError.value = ""; };
const submitPhoto = async () => {
if (uploading.value || submitting.value || !hasValidContext.value) return;
@@ -120,8 +131,10 @@ const submitPhoto = async () => {
submitting.value = true;
submitError.value = "";
try {
const { shootDate, shootClock, ...photoForm } = form;
await appApi.createAlbumPhoto(genealogyId.value, albumId.value, {
...form,
...photoForm,
shootTime: shootTime.value,
ossId: toConsumerOssId(receipt.value.ossId),
}, { requestController: controller });
pageState.value = "success";
@@ -167,11 +180,13 @@ onUnmounted(() => {
.required-mark { display: inline-block; margin-right: 4rpx; color: $brand-red; font-size: 26rpx; line-height: 1; transform: translateY(-3rpx); }
.media-field input, .media-field textarea { @include adaptive.adaptive-family-field; box-sizing: border-box; display: block; width: 100%; color: $ink; font-size: 24rpx; }
.media-field input { min-height: 78rpx; padding: 0 22rpx; }
.media-field--picker picker { display: block; min-height: 78rpx; }
.media-field--picker picker > view { display: flex; min-height: 78rpx; align-items: center; padding: 0 22rpx; border: 1rpx solid rgba(128, 89, 49, .34); border-radius: 12rpx; background: rgba(255, 252, 245, .7); color: $ink; font-size: 24rpx; }
.media-field textarea { min-height: 116rpx; padding: 18rpx 22rpx; line-height: 1.55; }
.placeholder { color: #9e8e79; }
.media-field--upload { display: grid; gap: 12rpx; padding: 18rpx 20rpx; border: 1rpx solid rgba(128, 89, 49, .34); border-radius: 12rpx; background: rgba(255, 252, 245, .7); }
.media-field--upload .media-field__label { margin: 0; }
.upload-button { justify-self: start; min-height: 60rpx; margin: 0; padding: 0 20rpx; border: 1rpx solid rgba(159, 23, 15, .42); border-radius: 8rpx; background: transparent; color: $brand-red; font-size: 22rpx; }
.upload-button { justify-self: start; min-height: 88rpx; margin: 0; padding: 0 20rpx; border: 1rpx solid rgba(159, 23, 15, .42); border-radius: 8rpx; background: transparent; color: $brand-red; font-size: 22rpx; }
.upload-receipt { color: $ink-muted; font-size: 21rpx; overflow-wrap: anywhere; }
.field-error { margin-top: 10rpx; color: $brand-red; font-size: 22rpx; line-height: 1.45; }
.media-panel .app-button { margin-top: 28rpx; }