待测试

This commit is contained in:
rain
2026-07-27 17:17:31 +08:00
parent 1eae3bbef4
commit 04287e6777
35 changed files with 4238 additions and 22750 deletions
+22 -4
View File
@@ -32,6 +32,18 @@
<text class="field-row__label">地点</text>
<input v-model="form.location" maxlength="60" placeholder="请输入地点" placeholder-class="placeholder" @input="clearError" />
</view>
<view class="field-row">
<text class="field-row__label">详细地址</text>
<input v-model="form.locationAddress" maxlength="120" placeholder="请输入详细地址" placeholder-class="placeholder" @input="clearError" />
</view>
<view class="field-row">
<text class="field-row__label">经度</text>
<input v-model="form.longitude" type="digit" placeholder="地图选点后填写" placeholder-class="placeholder" @input="clearError" />
</view>
<view class="field-row">
<text class="field-row__label">纬度</text>
<input v-model="form.latitude" type="digit" placeholder="地图选点后填写" placeholder-class="placeholder" @input="clearError" />
</view>
<view class="cover-field">
<view>
<text class="cover-field__label">封面图片</text>
@@ -66,13 +78,13 @@ import AppDialog from "@/components/AppDialog.vue";
import ModulePageBackground from "@/components/ModulePageBackground.vue";
import PageHeader from "@/components/PageHeader.vue";
import { appApi, createRequestController, isRequestCancelled } from "@/utils/api.js";
import { isImagePickCancelled, pickAndUploadImage, toConsumerOssId } from "@/utils/resumable-image-upload.js";
import { isImagePickCancelled, pickAndUploadImage } from "@/utils/resumable-image-upload.js";
import { createDiscardConfirmation } from "@/utils/discard-confirmation.js";
import { goBack, handleBackPress, returnTo, runBackGuard } from "@/utils/navigation.js";
const genealogyId = ref("");
const pageState = ref("form");
const form = reactive({ ceremonyType: "", ceremonyTitle: "", ceremonyDesc: "", ceremonyDate: "", ceremonyClock: "", location: "", sortOrder: "" });
const form = reactive({ ceremonyType: "", ceremonyTitle: "", ceremonyDesc: "", ceremonyDate: "", ceremonyClock: "", location: "", locationAddress: "", longitude: "", latitude: "", sortOrder: "" });
const coverOssId = ref(null);
const coverFileName = ref("");
const uploadError = ref("");
@@ -103,7 +115,7 @@ const uploadCover = async () => {
uploadError.value = "";
try {
const receipt = await pickAndUploadImage({ requestController: controller });
coverOssId.value = toConsumerOssId(receipt.ossId);
coverOssId.value = receipt.ossId;
coverFileName.value = receipt.fileName || "活动封面";
} catch (error) {
if (!isImagePickCancelled(error) && !isRequestCancelled(error)) uploadError.value = error?.message || "封面图片上传失败,请稍后重试";
@@ -121,7 +133,13 @@ const submit = async () => {
submitError.value = "";
try {
const { ceremonyDate, ceremonyClock, ...ceremonyForm } = form;
await appApi.createCeremony(genealogyId.value, { ...ceremonyForm, ceremonyTime: ceremonyTime.value, ...(coverOssId.value ? { coverOssId: coverOssId.value } : {}) }, { requestController: controller });
await appApi.createCeremony(genealogyId.value, {
...ceremonyForm,
ceremonyTime: ceremonyTime.value,
...(form.longitude ? { longitude: Number(form.longitude) } : {}),
...(form.latitude ? { latitude: Number(form.latitude) } : {}),
...(coverOssId.value ? { coverOssId: coverOssId.value } : {}),
}, { requestController: controller });
pageState.value = "success";
} catch (error) {
if (!isRequestCancelled(error)) submitError.value = error?.message || "礼仪活动保存失败,请稍后重试";
+10 -1
View File
@@ -8,6 +8,7 @@
<text>新建功德记录</text>
<text class="form-copy">红色 * 为必填项其余内容可按需补充</text>
<view v-for="field in fields" :key="field.key" class="field"><text><text v-if="field.required" class="required-mark">*</text>{{ field.label }}</text><textarea v-if="field.key === 'content'" v-model="form[field.key]" auto-height :placeholder="`请输入${field.label}`" @input="error = ''" /><input v-else v-model="form[field.key]" :type="field.inputType || 'text'" :placeholder="field.placeholder || `请输入${field.label}`" @input="error = ''" /></view>
<view class="field field--picker"><text>功德类型</text><picker :range="meritTypeOptions.map((item) => item.label)" :value="meritTypeIndex" @change="selectMeritType"><view :class="{ placeholder: !form.type }">{{ meritTypeLabel || '请选择' }}</view></picker></view>
<view class="field field--picker"><text>记录日期</text><picker mode="date" :value="form.meritDate" @change="selectMeritDate"><view :class="{ placeholder: !form.meritDate }">{{ form.meritDate || '请选择' }}</view></picker></view>
<view class="field field--picker"><text>记录时间</text><picker mode="time" :value="form.meritClock" @change="selectMeritClock"><view :class="{ placeholder: !form.meritClock }">{{ form.meritClock || '请选择' }}</view></picker></view>
<text v-if="error" class="error">{{ error }}</text>
@@ -51,16 +52,23 @@ const form = reactive({ donor: "", title: "", type: "", amount: "", meritDate: "
const fields = [
{ key: "donor", label: "捐赠人", required: true },
{ key: "title", label: "功德标题", required: true },
{ key: "type", label: "功德类型" },
{ key: "amount", inputType: "digit", label: "金额" },
{ key: "content", label: "记录内容" },
{ key: "sortOrder", label: "排序值", inputType: "number", placeholder: "数值越小越靠前" },
];
const meritTypeOptions = Object.freeze([
{ value: "donation", label: "捐赠" },
{ value: "repair", label: "修祠" },
{ value: "public", label: "公益" },
{ value: "other", label: "其他" },
]);
const controller = createRequestController();
let active = true;
const valid = computed(() => /^[1-9]\d*$/.test(genealogyId.value));
const dirty = computed(() => Object.values(form).some((value) => String(value).trim()));
const meritTime = computed(() => form.meritDate ? `${form.meritDate} ${form.meritClock || "00:00"}:00` : "");
const meritTypeIndex = computed(() => Math.max(0, meritTypeOptions.findIndex((item) => item.value === form.type)));
const meritTypeLabel = computed(() => meritTypeOptions.find((item) => item.value === form.type)?.label || "");
const totalAmount = computed(() => merits.value.reduce((total, item) => total + item.amount, 0).toFixed(2));
const confirmation = createDiscardConfirmation((visible) => { discardVisible.value = visible; });
const confirmDiscard = () => { confirmation.confirm(); resetForm(); view.value = "list"; };
@@ -93,6 +101,7 @@ const openCreate = () => { if (!valid.value) return; saveNotice.value = false; r
const cancelCreate = () => { resetForm(); view.value = "list"; };
const selectMeritDate = (event) => { form.meritDate = event.detail.value || ""; error.value = ""; };
const selectMeritClock = (event) => { form.meritClock = event.detail.value || ""; error.value = ""; };
const selectMeritType = (event) => { form.type = meritTypeOptions[Number(event.detail.value)]?.value || ""; error.value = ""; };
const submit = async () => {
if (submitting.value || !valid.value) return;
const donorName = form.donor.trim();