完成50%
This commit is contained in:
@@ -4,11 +4,12 @@
|
||||
class="publish-page"
|
||||
:class="{
|
||||
'publish-state--form': publishState === 'form',
|
||||
'publish-state--success': publishState === 'success',
|
||||
'publish-state--preview': publishState === 'preview',
|
||||
'publish-state--error': publishState === 'error',
|
||||
'publish-state--invalid': publishState === 'invalid',
|
||||
}"
|
||||
><ModulePageBackground module="family" /><view class="publish-page__header"
|
||||
><PageHeader title="发布动态" /></view
|
||||
><PageHeader title="发布动态" custom-back @back="requestBack" /></view
|
||||
><view class="publish-panel"
|
||||
><view
|
||||
v-if="publishState === 'form'"
|
||||
@@ -23,42 +24,99 @@
|
||||
placeholder="写下想对家人说的话"
|
||||
placeholder-class="publish-placeholder"
|
||||
/></view
|
||||
><AppButton block label="发布动态" @click="submit" /></view
|
||||
><view v-else class="publish-result"
|
||||
><text>{{
|
||||
publishState === "success" ? "动态已发布" : "动态未发布"
|
||||
}}</text
|
||||
><text>{{
|
||||
publishState === "success"
|
||||
? "家人现在可以在家族圈看到这条记录。"
|
||||
: "请检查内容后重新发布,当前文字仍保留在页面中。"
|
||||
}}</text
|
||||
><AppButton
|
||||
block
|
||||
:label="publishState === 'success' ? '继续发布' : '重新填写'"
|
||||
@click="publishState = 'form'" /></view></view
|
||||
:label="isSubmitting ? '正在校验' : '生成本地预览'"
|
||||
:disabled="isSubmitting"
|
||||
@click="submit"
|
||||
/></view
|
||||
><view v-else class="publish-result"
|
||||
><text>{{ resultCopy.title }}</text
|
||||
><text>{{ resultCopy.copy }}</text
|
||||
><AppButton
|
||||
block
|
||||
:label="resultCopy.action"
|
||||
@click="handleResultAction" /></view></view
|
||||
><AppDialog
|
||||
:visible="discardVisible"
|
||||
title="放弃动态草稿?"
|
||||
message="当前内容尚未提交服务器,确认返回后不会保留。"
|
||||
confirm-text="放弃并返回"
|
||||
cancel-text="继续填写"
|
||||
show-cancel
|
||||
:close-on-mask="false"
|
||||
@confirm="confirmDiscard"
|
||||
@cancel="cancelDiscard"
|
||||
/>
|
||||
><AppToast :visible="toastVisible" :message="toastMessage"
|
||||
/></view>
|
||||
</template>
|
||||
<script setup>
|
||||
import { onUnmounted, ref } from "vue";
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import { computed, onUnmounted, ref } from "vue";
|
||||
import { onBackPress, onLoad } from "@dcloudio/uni-app";
|
||||
import AppButton from "@/components/AppButton.vue";
|
||||
import AppDialog from "@/components/AppDialog.vue";
|
||||
import AppToast from "@/components/AppToast.vue";
|
||||
import ModulePageBackground from "@/components/ModulePageBackground.vue";
|
||||
import PageHeader from "@/components/PageHeader.vue";
|
||||
import { getGenealogyFixtureAccess } from "@/data/mock.js";
|
||||
import { createDiscardConfirmation } from "@/utils/discard-confirmation.js";
|
||||
import {
|
||||
goBack,
|
||||
handleBackPress,
|
||||
returnTo,
|
||||
runBackGuard,
|
||||
} from "@/utils/navigation.js";
|
||||
|
||||
const genealogyId = ref("");
|
||||
const content = ref("");
|
||||
const publishState = ref("form");
|
||||
const isSubmitting = ref(false);
|
||||
const discardVisible = ref(false);
|
||||
const toastVisible = ref(false);
|
||||
const toastMessage = ref("");
|
||||
let toastTimer = null;
|
||||
let submitTimer = null;
|
||||
const isDirty = computed(() => Boolean(content.value.trim()));
|
||||
const hasValidContext = computed(() =>
|
||||
["owner", "member"].includes(
|
||||
getGenealogyFixtureAccess(genealogyId.value).accessRole,
|
||||
),
|
||||
);
|
||||
const resultCopy = computed(() => ({
|
||||
preview: {
|
||||
title: "动态内容已完成本地预览",
|
||||
copy: "当前尚未提交服务器,返回家族圈后不会出现这条动态。",
|
||||
action: "返回家族圈(不发布)",
|
||||
},
|
||||
error: {
|
||||
title: "动态未提交",
|
||||
copy: "当前文字仍保留在页面中,可返回表单继续核对。",
|
||||
action: "返回填写",
|
||||
},
|
||||
invalid: {
|
||||
title: "动态入口无效",
|
||||
copy: "没有找到可发布内容的成员家谱,页面不会创建无归属动态。",
|
||||
action: "返回上一页",
|
||||
},
|
||||
}[publishState.value]));
|
||||
const discardConfirmation = createDiscardConfirmation((visible) => {
|
||||
discardVisible.value = visible;
|
||||
});
|
||||
const requestDiscardConfirmation = discardConfirmation.request;
|
||||
const confirmDiscard = discardConfirmation.confirm;
|
||||
const cancelDiscard = discardConfirmation.cancel;
|
||||
|
||||
onLoad((query) => {
|
||||
publishState.value =
|
||||
query.state === "success"
|
||||
? "success"
|
||||
: query.state === "error"
|
||||
? "error"
|
||||
: "form";
|
||||
genealogyId.value = String(query.genealogyId || "");
|
||||
if (!genealogyId.value || !hasValidContext.value) {
|
||||
publishState.value = "invalid";
|
||||
return;
|
||||
}
|
||||
if (["preview", "error"].includes(query.state)) {
|
||||
content.value = "这是一段尚未提交服务器的家族动态预览。";
|
||||
publishState.value = query.state;
|
||||
}
|
||||
});
|
||||
const showToast = (message) => {
|
||||
toastMessage.value = message;
|
||||
@@ -70,14 +128,48 @@ const showToast = (message) => {
|
||||
}, 1800);
|
||||
};
|
||||
const submit = () => {
|
||||
if (isSubmitting.value || !hasValidContext.value) return;
|
||||
if (!content.value.trim()) {
|
||||
showToast("请先写下动态内容");
|
||||
return;
|
||||
}
|
||||
publishState.value = "success";
|
||||
isSubmitting.value = true;
|
||||
const submittedContent = content.value.trim();
|
||||
const timer = setTimeout(() => {
|
||||
if (submitTimer !== timer) return;
|
||||
submitTimer = null;
|
||||
isSubmitting.value = false;
|
||||
publishState.value = submittedContent ? "preview" : "error";
|
||||
}, 280);
|
||||
submitTimer = timer;
|
||||
};
|
||||
const requestBack = () =>
|
||||
runBackGuard({
|
||||
transientOpen: discardVisible.value,
|
||||
dirty: isDirty.value,
|
||||
submitting: isSubmitting.value,
|
||||
"close-transient": cancelDiscard,
|
||||
"block-submitting": () => true,
|
||||
"confirm-discard": requestDiscardConfirmation,
|
||||
});
|
||||
const returnToFamily = async () => {
|
||||
const confirmed = isDirty.value ? await requestDiscardConfirmation() : true;
|
||||
if (!confirmed) return false;
|
||||
return returnTo("F01", { genealogyId: genealogyId.value });
|
||||
};
|
||||
const handleResultAction = () => {
|
||||
if (publishState.value === "preview") return returnToFamily();
|
||||
if (publishState.value === "error") {
|
||||
publishState.value = "form";
|
||||
return;
|
||||
}
|
||||
return goBack();
|
||||
};
|
||||
onBackPress((event) => handleBackPress(event, requestBack));
|
||||
onUnmounted(() => {
|
||||
if (toastTimer) clearTimeout(toastTimer);
|
||||
if (submitTimer) clearTimeout(submitTimer);
|
||||
discardConfirmation.dispose();
|
||||
});
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
|
||||
Reference in New Issue
Block a user