完成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
+15 -7
View File
@@ -20,9 +20,13 @@
<text class="textarea-field__label">活动说明</text>
<textarea v-model="form.ceremonyDesc" maxlength="500" auto-height placeholder="补充活动安排或说明" placeholder-class="placeholder" @input="clearError" />
</view>
<view class="field-row">
<view class="field-row field-row--picker">
<text class="field-row__label">活动日期</text>
<picker mode="date" :value="form.ceremonyDate" @change="selectCeremonyDate"><view :class="{ placeholder: !form.ceremonyDate }">{{ form.ceremonyDate || '请选择' }}</view></picker>
</view>
<view class="field-row field-row--picker">
<text class="field-row__label">活动时间</text>
<input v-model="form.ceremonyTime" maxlength="30" placeholder="例如:2026-07-24 10:00:00" placeholder-class="placeholder" @input="clearError" />
<picker mode="time" :value="form.ceremonyClock" @change="selectCeremonyClock"><view :class="{ placeholder: !form.ceremonyClock }">{{ form.ceremonyClock || '请选择' }}</view></picker>
</view>
<view class="field-row">
<text class="field-row__label">地点</text>
@@ -68,7 +72,7 @@ import { goBack, handleBackPress, returnTo, runBackGuard } from "@/utils/navigat
const genealogyId = ref("");
const pageState = ref("form");
const form = reactive({ ceremonyType: "", ceremonyTitle: "", ceremonyDesc: "", ceremonyTime: "", location: "", sortOrder: "" });
const form = reactive({ ceremonyType: "", ceremonyTitle: "", ceremonyDesc: "", ceremonyDate: "", ceremonyClock: "", location: "", sortOrder: "" });
const coverOssId = ref(null);
const coverFileName = ref("");
const uploadError = ref("");
@@ -80,7 +84,8 @@ const discardVisible = ref(false);
const confirmation = createDiscardConfirmation((visible) => { discardVisible.value = visible; });
const hasValidContext = computed(() => /^[1-9]\d*$/.test(genealogyId.value));
const isDirty = computed(() => coverOssId.value || Object.values(form).some((value) => value.trim()));
const isDirty = computed(() => Boolean(coverOssId.value) || Object.values(form).some((value) => value.trim()));
const ceremonyTime = computed(() => form.ceremonyDate ? `${form.ceremonyDate} ${form.ceremonyClock || "00:00"}:00` : "");
const stateCopy = computed(() => pageState.value === "success"
? { title: "礼仪活动已提交服务端", copy: "服务端已返回成功结果。", action: "返回礼仪活动" }
: { title: "礼仪活动入口无效", copy: "没有取得有效家谱标识。", action: "返回上一页" });
@@ -90,6 +95,8 @@ onLoad((query) => {
if (!hasValidContext.value || query?.mode !== "create") pageState.value = "invalid";
});
const clearError = () => { submitError.value = ""; };
const selectCeremonyDate = (event) => { form.ceremonyDate = event.detail.value || ""; clearError(); };
const selectCeremonyClock = (event) => { form.ceremonyClock = event.detail.value || ""; clearError(); };
const uploadCover = async () => {
if (uploading.value || submitting.value) return;
uploading.value = true;
@@ -113,7 +120,8 @@ const submit = async () => {
submitting.value = true;
submitError.value = "";
try {
await appApi.createCeremony(genealogyId.value, { ...form, ...(coverOssId.value ? { coverOssId: coverOssId.value } : {}) }, { requestController: controller });
const { ceremonyDate, ceremonyClock, ...ceremonyForm } = form;
await appApi.createCeremony(genealogyId.value, { ...ceremonyForm, ceremonyTime: ceremonyTime.value, ...(coverOssId.value ? { coverOssId: coverOssId.value } : {}) }, { requestController: controller });
pageState.value = "success";
} catch (error) {
if (!isRequestCancelled(error)) submitError.value = error?.message || "礼仪活动保存失败,请稍后重试";
@@ -135,8 +143,8 @@ onUnmounted(() => { controller.abort(); confirmation.dispose(); });
.editor-card,.state-card { @include adaptive.adaptive-records-content; box-sizing:border-box; }
.editor-card { padding:38rpx 32rpx 42rpx; }.editor-card__title,.editor-card__note,.field-row__label,.textarea-field__label,.form-error { display:block; }
.editor-card__title { color:$ink; font-family:STKaiti,KaiTi,serif; font-size:38rpx; font-weight:700; }.editor-card__note { margin-top:10rpx; color:$ink-muted; font-size:23rpx; line-height:1.55; }
.field-row { display:flex; min-height:92rpx; align-items:center; margin-top:20rpx; padding:0 18rpx; border:1rpx solid rgba(128,89,49,.34); border-radius:12rpx; background:rgba(255,252,245,.7); }.field-row__label { width:150rpx; flex:0 0 auto; color:$ink; font-size:26rpx; font-weight:700; }.field-row input { min-width:0; flex:1; color:$ink; font-size:25rpx; }.required-mark { display:inline-block; margin-right:4rpx; color:$brand-red; font-size:26rpx; transform:translateY(-3rpx); }.placeholder { color:#9e8e79; }
.field-row { display:flex; min-height:92rpx; align-items:center; margin-top:20rpx; padding:0 18rpx; border:1rpx solid rgba(128,89,49,.34); border-radius:12rpx; background:rgba(255,252,245,.7); }.field-row__label { width:150rpx; flex:0 0 auto; color:$ink; font-size:26rpx; font-weight:700; }.field-row input { min-width:0; flex:1; color:$ink; font-size:25rpx; }.field-row--picker picker { min-width:0; flex:1; }.field-row--picker picker > view { min-height:92rpx; display:flex; align-items:center; color:$ink; font-size:25rpx; }.required-mark { display:inline-block; margin-right:4rpx; color:$brand-red; font-size:26rpx; transform:translateY(-3rpx); }.placeholder { color:#9e8e79; }
.textarea-field,.cover-field { margin-top:20rpx; padding:18rpx; border:1rpx solid rgba(128,89,49,.34); border-radius:12rpx; background:rgba(255,252,245,.7); }.textarea-field__label,.cover-field__label { color:$ink; font-size:26rpx; font-weight:700; }.textarea-field textarea { display:block; width:100%; min-height:122rpx; margin-top:12rpx; color:$ink; font-size:25rpx; line-height:1.55; }
.cover-field { display:grid; gap:12rpx; }.cover-field__hint { display:block; margin-top:5rpx; color:$ink-muted; font-size:20rpx; line-height:1.45; }.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-receipt { color:$ink-muted; font-size:21rpx; overflow-wrap:anywhere; }.form-error { margin-top:10rpx; color:$brand-red; font-size:22rpx; line-height:1.45; }.editor-card .app-button { margin-top:28rpx; }
.cover-field { display:grid; gap:12rpx; }.cover-field__hint { display:block; margin-top:5rpx; color:$ink-muted; font-size:20rpx; line-height:1.45; }.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; }.form-error { margin-top:10rpx; color:$brand-red; font-size:22rpx; line-height:1.45; }.editor-card .app-button { margin-top:28rpx; }
.state-card { min-height:340rpx; padding:78rpx 52rpx 50rpx; text-align:center; }.state-card text { display:block; }.state-card text:first-child { color:$ink; font-size:35rpx; font-weight:700; }.state-card text:nth-child(2) { margin-top:18rpx; color:$ink-muted; font-size:24rpx; line-height:1.65; }.state-card .app-button { margin-top:28rpx; }
</style>