修改完成
This commit is contained in:
@@ -1,5 +1,227 @@
|
||||
<!-- 页面编号:R-07;用途:新建与编辑礼仪。 -->
|
||||
<template><ModulePage page-id="r07" /></template>
|
||||
<!-- 页面编号:R-07;用途:礼仪创建、编辑、校验、保存与删除确认。 -->
|
||||
<template>
|
||||
<view class="ritual-editor-page" :class="editorClasses">
|
||||
<ModulePageBackground module="records" />
|
||||
<view class="page-header">
|
||||
<PageHeader :title="mode === 'create' ? '新建礼仪' : '编辑礼仪'" />
|
||||
</view>
|
||||
<view class="page-content">
|
||||
<view v-if="editorState === 'success'" class="state-card">
|
||||
<text>礼仪活动已保存</text>
|
||||
<text>时间、地点与活动说明已整理完成。</text>
|
||||
<AppButton block label="返回礼仪列表" @click="backToRituals" />
|
||||
</view>
|
||||
<view v-else class="form-card">
|
||||
<text>
|
||||
{{ mode === "create" ? "安排一次家族礼仪" : "修改活动信息" }}
|
||||
</text>
|
||||
<view v-for="field in fields" :key="field.key" class="field-row">
|
||||
<text>{{ field.label }}</text>
|
||||
<textarea
|
||||
v-if="field.long"
|
||||
v-model="ritualForm[field.key]"
|
||||
auto-height
|
||||
:placeholder="`请输入${field.label}`"
|
||||
/>
|
||||
<input
|
||||
v-else
|
||||
v-model="ritualForm[field.key]"
|
||||
:placeholder="`请输入${field.label}`"
|
||||
/>
|
||||
<text v-if="ritualErrors[field.key]">
|
||||
{{ ritualErrors[field.key] }}
|
||||
</text>
|
||||
</view>
|
||||
<text v-if="editorState === 'error'" class="save-error">
|
||||
保存失败,请保留内容后重试。
|
||||
</text>
|
||||
<AppButton
|
||||
block
|
||||
:disabled="editorState === 'saving'"
|
||||
:label="editorState === 'saving' ? '正在保存' : '保存活动'"
|
||||
@click="saveRitual"
|
||||
/>
|
||||
<AppButton
|
||||
v-if="mode === 'edit'"
|
||||
type="secondary"
|
||||
block
|
||||
label="删除活动"
|
||||
@click="confirmDelete"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<AppDialog
|
||||
:visible="deleteVisible"
|
||||
eyebrow="删除确认"
|
||||
title="删除这项礼仪活动?"
|
||||
message="删除后将返回礼仪列表。"
|
||||
confirm-text="确认删除"
|
||||
cancel-text="保留活动"
|
||||
show-cancel
|
||||
@confirm="deleteRitual"
|
||||
@cancel="deleteVisible = false"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
<script setup>
|
||||
import ModulePage from "@/components/ModulePage.vue";
|
||||
import { computed, onUnmounted, reactive, ref } from "vue";
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import AppButton from "@/components/AppButton.vue";
|
||||
import AppDialog from "@/components/AppDialog.vue";
|
||||
import AppLoading from "@/components/AppLoading.vue";
|
||||
import ModulePageBackground from "@/components/ModulePageBackground.vue";
|
||||
import PageHeader from "@/components/PageHeader.vue";
|
||||
const records = [
|
||||
{
|
||||
id: "501",
|
||||
name: "清明祭祖",
|
||||
date: "2025-04-04",
|
||||
place: "汤氏宗祠",
|
||||
description: "缅怀先祖,凝聚家人,共叙家风传承。",
|
||||
},
|
||||
];
|
||||
const ritualId = ref("");
|
||||
const mode = ref("create");
|
||||
const editorState = ref("ready");
|
||||
const deleteVisible = ref(false);
|
||||
const forceSaveFailure = ref(false);
|
||||
const ritualForm = reactive({ name: "", date: "", place: "", description: "" });
|
||||
const ritualErrors = reactive({
|
||||
name: "",
|
||||
date: "",
|
||||
place: "",
|
||||
description: "",
|
||||
});
|
||||
const fields = [
|
||||
{ key: "name", label: "活动名称" },
|
||||
{ key: "date", label: "活动日期" },
|
||||
{ key: "place", label: "举办地点" },
|
||||
{ key: "description", label: "活动说明", long: true },
|
||||
];
|
||||
let saveTimer = null;
|
||||
const editorClasses = computed(() => ({
|
||||
"ritual-editor-state--saving": editorState.value === "saving",
|
||||
"ritual-editor-state--error": editorState.value === "error",
|
||||
}));
|
||||
onLoad((q) => {
|
||||
ritualId.value = String(q.ritualId || "");
|
||||
mode.value = q.mode === "edit" ? "edit" : "create";
|
||||
forceSaveFailure.value = q.saveResult === "error";
|
||||
const selected = records.find((x) => x.id === ritualId.value);
|
||||
if (selected) Object.assign(ritualForm, selected);
|
||||
});
|
||||
const validateRitual = () => {
|
||||
for (const f of fields)
|
||||
ritualErrors[f.key] = String(ritualForm[f.key]).trim()
|
||||
? ""
|
||||
: `请填写${f.label}`;
|
||||
return fields.every((f) => !ritualErrors[f.key]);
|
||||
};
|
||||
const saveRitual = () => {
|
||||
if (editorState.value === "saving" || !validateRitual()) return;
|
||||
editorState.value = "saving";
|
||||
saveTimer = setTimeout(() => {
|
||||
editorState.value = forceSaveFailure.value ? "error" : "success";
|
||||
forceSaveFailure.value = false;
|
||||
}, 320);
|
||||
};
|
||||
const confirmDelete = () => {
|
||||
deleteVisible.value = true;
|
||||
};
|
||||
const deleteRitual = () => {
|
||||
deleteVisible.value = false;
|
||||
backToRituals();
|
||||
};
|
||||
const backToRituals = () =>
|
||||
uni.redirectTo({ url: "/pages/records/r05-ritual-list" });
|
||||
onUnmounted(() => {
|
||||
if (saveTimer) clearTimeout(saveTimer);
|
||||
});
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.ritual-editor-page {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
flex-direction: column;
|
||||
background: $paper;
|
||||
}
|
||||
.page-header,
|
||||
.page-content {
|
||||
z-index: 1;
|
||||
}
|
||||
.page-content {
|
||||
padding: 18rpx 24rpx 72rpx;
|
||||
}
|
||||
.form-card,
|
||||
.state-card {
|
||||
box-sizing: border-box;
|
||||
padding: 46rpx;
|
||||
background: url("/static/assets/modules/records/transparent/module-content-frame.png")
|
||||
center/100% 100% no-repeat;
|
||||
}
|
||||
.form-card > text:first-child,
|
||||
.state-card > text:first-child {
|
||||
display: block;
|
||||
color: $ink;
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
.field-row {
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(0, 1fr);
|
||||
align-items: center;
|
||||
gap: 10rpx 18rpx;
|
||||
min-height: 82rpx;
|
||||
margin-top: 14rpx;
|
||||
padding: 14rpx 24rpx;
|
||||
box-sizing: border-box;
|
||||
background: url("/static/assets/modules/records/transparent/module-field-frame.png")
|
||||
center/100% 100% no-repeat;
|
||||
}
|
||||
.field-row > text:first-child {
|
||||
color: $ink;
|
||||
font-size: 23rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
.field-row input,
|
||||
.field-row textarea {
|
||||
width: auto;
|
||||
min-width: 0;
|
||||
color: $ink;
|
||||
font-size: 23rpx;
|
||||
text-align: right;
|
||||
}
|
||||
.field-row textarea {
|
||||
min-height: 76rpx;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.field-row > text:last-child {
|
||||
grid-column: 1/-1;
|
||||
color: $brand-red;
|
||||
font-size: 20rpx;
|
||||
text-align: right;
|
||||
}
|
||||
.form-card .app-button {
|
||||
margin-top: 18rpx;
|
||||
}
|
||||
.save-error {
|
||||
display: block;
|
||||
margin-top: 14rpx;
|
||||
color: $brand-red;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
.state-card {
|
||||
min-height: 340rpx;
|
||||
padding-top: 80rpx;
|
||||
text-align: center;
|
||||
}
|
||||
.state-card > text:nth-child(2) {
|
||||
display: block;
|
||||
margin-top: 18rpx;
|
||||
color: $ink-muted;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.state-card .app-button {
|
||||
margin-top: 28rpx;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user