验收完成40%
This commit is contained in:
@@ -198,16 +198,18 @@ defineEmits(["select"]);
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
.card-meta {
|
||||
color: $ink-muted;
|
||||
color: #62584c;
|
||||
font-size: 26rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
.card-updated {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
margin-left: 10rpx;
|
||||
color: $ink-muted;
|
||||
font-size: 22rpx;
|
||||
color: #62584c;
|
||||
font-size: 24rpx;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@@ -224,8 +226,9 @@ defineEmits(["select"]);
|
||||
}
|
||||
|
||||
.card-role {
|
||||
color: $ink-muted;
|
||||
font-size: 24rpx;
|
||||
color: #62584c;
|
||||
font-size: 26rpx;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.card-chevron {
|
||||
|
||||
+28
-20
@@ -9,9 +9,8 @@
|
||||
'module-state--error': moduleState === 'error'
|
||||
}
|
||||
]">
|
||||
<image class="module-page__paper" src="/static/assets/foundation/opaque/page-paper.jpg" mode="aspectFill" />
|
||||
<image class="module-page__footer" src="/static/assets/foundation/transparent/footer-mountain-bamboo.png" mode="widthFix" />
|
||||
<view class="module-page__header"><PageHeader :title="page.title" :action="page.number" /></view>
|
||||
<ModulePageBackground :module="moduleKey" />
|
||||
<view class="module-page__header"><PageHeader :title="page.title" /></view>
|
||||
|
||||
<view v-if="moduleState === 'ready'" class="module-page__content">
|
||||
<view class="page-intro">
|
||||
@@ -28,7 +27,7 @@
|
||||
<image src="/static/assets/modules/genealogy/opaque/g06-search-input-wide.png" mode="scaleToFill" /><text>{{ field }}</text><input :placeholder="`请输入${field}`" placeholder-class="form-placeholder" />
|
||||
</view>
|
||||
<text v-if="page.note" class="form-note">{{ normalizedNote }}</text>
|
||||
<view class="primary-action" @click="completeAction"><image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" /><text>{{ page.action }}</text></view>
|
||||
<AppButton block :label="page.action" @click="completeAction" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -37,7 +36,7 @@
|
||||
<image src="/static/assets/modules/genealogy/opaque/application-status-card.png" mode="scaleToFill" />
|
||||
<view class="list-card__copy"><text>{{ item[0] }}</text><text>{{ item[1] }}</text><text>点按查看详情</text></view>
|
||||
</view>
|
||||
<view class="primary-action primary-action--compact" @click="completeAction"><image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" /><text>{{ page.action }}</text></view>
|
||||
<AppButton block :label="page.action" @click="completeAction" />
|
||||
</view>
|
||||
|
||||
<view v-else-if="page.template === 'detail'" class="module-panel module-panel--detail">
|
||||
@@ -49,7 +48,7 @@
|
||||
<view v-for="item in page.sections" :key="item[0]" class="detail-card">
|
||||
<image src="/static/assets/modules/genealogy/opaque/g06-search-input-wide.png" mode="scaleToFill" /><view><text>{{ item[0] }}</text><text>{{ item[1] }}</text></view>
|
||||
</view>
|
||||
<view class="primary-action" @click="completeAction"><image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" /><text>{{ page.action }}</text></view>
|
||||
<AppButton block :label="page.action" @click="completeAction" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -58,7 +57,7 @@
|
||||
<image src="/static/assets/modules/genealogy/opaque/application-status-card.png" mode="scaleToFill" />
|
||||
<view><text>第 {{ index + 1 }} 则</text><text>{{ item[0] }}</text><text>{{ item[1] }}</text></view>
|
||||
</view>
|
||||
<view class="primary-action primary-action--compact" @click="completeAction"><image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" /><text>{{ page.action }}</text></view>
|
||||
<AppButton block :label="page.action" @click="completeAction" />
|
||||
</view>
|
||||
|
||||
<view v-else-if="page.template === 'settings'" class="module-panel">
|
||||
@@ -68,7 +67,7 @@
|
||||
<view v-for="item in page.sections" :key="item[0]" class="settings-row" @click="openPreview(item)">
|
||||
<image src="/static/assets/modules/genealogy/opaque/g06-search-input-wide.png" mode="scaleToFill" /><view><text>{{ item[0] }}</text><text>{{ item[1] }}</text></view><text>查看</text>
|
||||
</view>
|
||||
<view class="primary-action" @click="completeAction"><image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" /><text>{{ page.action }}</text></view>
|
||||
<AppButton block :label="page.action" @click="completeAction" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -76,7 +75,7 @@
|
||||
<image class="module-panel__skin" src="/static/assets/modules/genealogy/opaque/g03-create-flow-panel.png" mode="scaleToFill" />
|
||||
<view class="module-panel__body status-card">
|
||||
<text class="status-card__eyebrow">{{ page.badge }} · 服务说明</text><text class="status-card__lead">{{ page.lead }}</text><text class="status-card__note">{{ normalizedNote }}</text>
|
||||
<view class="primary-action" @click="completeAction"><image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" /><text>{{ page.action }}</text></view>
|
||||
<AppButton block :label="page.action" @click="completeAction" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -86,27 +85,35 @@
|
||||
<image class="module-panel__skin" src="/static/assets/modules/genealogy/opaque/g03-create-flow-panel.png" mode="scaleToFill" />
|
||||
<view class="module-panel__body status-card">
|
||||
<text class="status-card__eyebrow">{{ stateCopy.eyebrow }}</text><text class="status-card__lead">{{ stateCopy.title }}</text><text class="status-card__note">{{ stateCopy.copy }}</text>
|
||||
<view class="primary-action" @click="moduleState = 'ready'"><image :src="moduleState === 'error' ? '/static/assets/foundation/opaque/a01-secondary-button.png' : '/static/assets/foundation/opaque/a01-primary-button.png'" mode="scaleToFill" /><text :class="{ 'primary-action__secondary': moduleState === 'error' }">{{ stateCopy.action }}</text></view>
|
||||
<AppButton block :type="moduleState === 'error' ? 'secondary' : 'primary'" :label="stateCopy.action" @click="moduleState = 'ready'" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<AppTabbar v-if="page.tab" :active="page.tab" />
|
||||
<AppToast :visible="toastVisible" :message="toastMessage" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue'
|
||||
import { computed, onUnmounted, ref } from 'vue'
|
||||
import AppButton from '@/components/AppButton.vue'
|
||||
import PageHeader from '@/components/PageHeader.vue'
|
||||
import AppTabbar from '@/components/AppTabbar.vue'
|
||||
import AppToast from '@/components/AppToast.vue'
|
||||
import ModulePageBackground from '@/components/ModulePageBackground.vue'
|
||||
import { pageCatalog } from '@/data/page-catalog.js'
|
||||
|
||||
const props = defineProps({ pageId: { type: String, required: true } })
|
||||
const page = computed(() => pageCatalog[props.pageId])
|
||||
const moduleKey = computed(() => ({ f: 'family', r: 'records', n: 'notification', m: 'profile' }[props.pageId[0]] || 'profile'))
|
||||
const query = (() => {
|
||||
if (typeof location !== 'undefined') return Object.fromEntries(new URLSearchParams(location.hash.split('?')[1] || ''))
|
||||
const pages = getCurrentPages(); return pages[pages.length - 1]?.options || {}
|
||||
})()
|
||||
const moduleState = ref('ready')
|
||||
const toastVisible = ref(false)
|
||||
const toastMessage = ref('')
|
||||
let toastTimer = null
|
||||
if (query.state === 'empty' || query.state === 'success' || query.state === 'error') moduleState.value = query.state
|
||||
const normalizedNote = computed(() => (page.value.note || '').replace(/待接入|服务待接入|功能待接入/g, '将在后续功能阶段开放'))
|
||||
const stateCopy = computed(() => ({
|
||||
@@ -115,13 +122,17 @@ const stateCopy = computed(() => ({
|
||||
error: { eyebrow: '内容暂不可用', title: `暂时无法打开${page.value.title}`, copy: '请稍后重新进入,现有资料不会受到影响。', action: '重新查看' }
|
||||
}[moduleState.value] || {}))
|
||||
const completeAction = () => { moduleState.value = 'success' }
|
||||
const openPreview = (item) => uni.showToast({ title: item[0], icon: 'none' })
|
||||
const openPreview = (item) => {
|
||||
toastMessage.value = item[0]
|
||||
toastVisible.value = true
|
||||
if (toastTimer) clearTimeout(toastTimer)
|
||||
toastTimer = setTimeout(() => { toastVisible.value = false; toastTimer = null }, 1800)
|
||||
}
|
||||
onUnmounted(() => { if (toastTimer) clearTimeout(toastTimer) })
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.module-page { position: relative; min-height: 100vh; overflow: hidden; background: $paper; }
|
||||
.module-page__paper { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; pointer-events: none; }
|
||||
.module-page__footer { position: absolute; right: 0; bottom: 0; left: 0; z-index: 1; width: 100%; opacity: .12; pointer-events: none; }
|
||||
.module-page__header, .module-page__content { position: relative; z-index: 2; }
|
||||
.module-page__content { padding: 20rpx 24rpx 50rpx; }
|
||||
.page-intro { display: flex; align-items: center; min-height: 86rpx; margin: 0 8rpx 14rpx; }
|
||||
@@ -135,15 +146,12 @@ const openPreview = (item) => uni.showToast({ title: item[0], icon: 'none' })
|
||||
.module-heading { display: block; color: $ink; font-family: STKaiti, KaiTi, serif; font-size: 34rpx; font-weight: 700; }
|
||||
.module-copy { display: block; margin-top: 8rpx; color: $ink-muted; font-size: 20rpx; line-height: 1.5; }
|
||||
.form-row { position: relative; height: 76rpx; margin-top: 12rpx; }
|
||||
.form-row image, .detail-card image, .settings-row image, .list-card > image, .timeline-row > image, .primary-action image { position: absolute; inset: 0; width: 100%; height: 100%; }
|
||||
.form-row image, .detail-card image, .settings-row image, .list-card > image, .timeline-row > image { position: absolute; inset: 0; width: 100%; height: 100%; }
|
||||
.form-row > text { position: absolute; top: 26rpx; left: 22rpx; z-index: 1; color: $ink; font-size: 21rpx; font-weight: 700; }
|
||||
.form-row input { position: absolute; top: 0; right: 18rpx; bottom: 0; left: 164rpx; z-index: 1; height: 76rpx; color: $ink; font-size: 21rpx; line-height: 76rpx; }
|
||||
.form-placeholder { color: #a79884; }
|
||||
.form-note { display: block; margin-top: 14rpx; color: $ink-muted; font-size: 19rpx; text-align: center; }
|
||||
.primary-action { position: relative; width: 100%; height: 76rpx; margin-top: 18rpx; }
|
||||
.primary-action text { position: relative; z-index: 1; display: flex; align-items: center; justify-content: center; height: 100%; color: #fff9ed; font-size: 24rpx; font-weight: 700; letter-spacing: 2rpx; }
|
||||
.primary-action .primary-action__secondary { color: $ink; }
|
||||
.primary-action--compact { width: 100%; }
|
||||
.module-form > .app-button, .module-detail > .app-button, .module-settings > .app-button, .content-stack > .app-button { margin-top: 18rpx; }
|
||||
.content-stack { display: flex; flex-direction: column; gap: 14rpx; }
|
||||
.list-card, .timeline-row { position: relative; width: 100%; height: calc((100vw - 24px) * .34286); min-height: 220rpx; }
|
||||
.list-card__copy { position: absolute; inset: 19% 9%; z-index: 1; }
|
||||
@@ -171,7 +179,7 @@ const openPreview = (item) => uni.showToast({ title: item[0], icon: 'none' })
|
||||
.status-card__eyebrow { display: block; color: $brand-red; font-size: 21rpx; letter-spacing: 3rpx; }
|
||||
.status-card__lead { display: block; margin-top: 14rpx; color: $ink; font-family: STKaiti, KaiTi, serif; font-size: 35rpx; font-weight: 700; }
|
||||
.status-card__note { display: block; margin-top: 17rpx; color: $ink-muted; font-size: 21rpx; line-height: 1.65; }
|
||||
.status-card .primary-action { width: 420rpx; max-width: 100%; margin: 30rpx auto 0; }
|
||||
.status-card .app-button { margin: 30rpx auto 0; }
|
||||
.module-page__content--state { padding-top: 18rpx; }
|
||||
@media (min-width: 400px) { .module-page__content { padding-right: 32rpx; padding-left: 32rpx; } }
|
||||
</style>
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
<view v-if="root" class="header-icon-button" @click="$emit('brand')">
|
||||
<image class="header-logo" src="/static/assets/foundation/transparent/brand-seal.png" mode="aspectFit" />
|
||||
</view>
|
||||
<view v-else class="header-back" @click="goBack">{{ backLabel }}</view>
|
||||
<view v-else class="header-back" hover-class="header-back--pressed" @click="goBack">
|
||||
<image class="header-back__icon" src="/static/assets/foundation/transparent/chevron-right.png" mode="aspectFit" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<text class="header-title">{{ title }}</text>
|
||||
@@ -27,7 +29,6 @@
|
||||
const props = defineProps({
|
||||
title: { type: String, required: true },
|
||||
action: { type: String, default: '' },
|
||||
backLabel: { type: String, default: '返回' },
|
||||
root: { type: Boolean, default: false },
|
||||
unreadCount: { type: Number, default: 0 }
|
||||
})
|
||||
@@ -114,13 +115,14 @@ const goBack = () => uni.navigateBack()
|
||||
background: #fff9ed;
|
||||
}
|
||||
|
||||
.header-back,
|
||||
.header-action {
|
||||
width: 100%;
|
||||
font-size: 27rpx;
|
||||
}
|
||||
|
||||
.header-back { text-align: left; }
|
||||
.header-back { display: flex; width: 88rpx; height: 88rpx; align-items: center; justify-content: flex-start; }
|
||||
.header-back__icon { width: 42rpx; height: 42rpx; filter: brightness(0) invert(1); transform: scaleX(-1); }
|
||||
.header-back--pressed { opacity: .62; }
|
||||
.header-action { color: #ffe3a7; text-align: right; }
|
||||
|
||||
.header-title {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
'form-state--conflict': formState === 'conflict',
|
||||
'form-state--error': formState === 'error'
|
||||
}">
|
||||
<image class="member-form-page__paper" src="/static/assets/foundation/opaque/page-paper.jpg" mode="aspectFill" />
|
||||
<ModulePageBackground module="tree" />
|
||||
<view class="member-form-page__header"><PageHeader :title="config.pageTitle" /></view>
|
||||
<view class="member-form-panel">
|
||||
<image class="member-form-panel__skin" src="/static/assets/modules/genealogy/opaque/g03-create-flow-panel.png" mode="scaleToFill" />
|
||||
@@ -22,7 +22,7 @@
|
||||
</view>
|
||||
<text class="member-form__note">{{ config.note }}</text>
|
||||
<view class="member-form-action" @click="saveForm">
|
||||
<image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" /><text>{{ config.action }}</text>
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="aspectFit" /><text>{{ config.action }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -32,36 +32,33 @@
|
||||
<text class="member-form__copy">{{ resultCopy.copy }}</text>
|
||||
<view v-if="formState === 'conflict'" class="conflict-actions">
|
||||
<view class="member-form-action" @click="formState = 'form'">
|
||||
<image src="/static/assets/foundation/opaque/a01-secondary-button.png" mode="scaleToFill" /><text class="member-form-action__secondary">返回核对</text>
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-secondary-v3.png" mode="aspectFit" /><text class="member-form-action__secondary">返回核对</text>
|
||||
</view>
|
||||
<view class="member-form-action" @click="showConflictHelp">
|
||||
<image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" /><text>查看冲突</text>
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="aspectFit" /><text>查看冲突</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else class="member-form-action" @click="formState = 'form'">
|
||||
<image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" /><text>{{ formState === 'success' ? '继续完善' : '重新填写' }}</text>
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="aspectFit" /><text>{{ formState === 'success' ? '继续完善' : '重新填写' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="conflictHelpVisible" class="conflict-help" @click.self="conflictHelpVisible = false">
|
||||
<view class="conflict-help__card">
|
||||
<image class="conflict-help__skin" src="/static/assets/modules/genealogy/opaque/application-status-card.png" mode="scaleToFill" />
|
||||
<view class="conflict-help__content">
|
||||
<text class="member-form__eyebrow">关系校验规则</text>
|
||||
<text class="member-form__title">关系冲突说明</text>
|
||||
<text class="member-form__copy">同一成员不能同时存在两个生父,也不能形成上下代循环。请返回世系树核对原关系后再调整。</text>
|
||||
<view class="member-form-action conflict-help__action" @click="conflictHelpVisible = false">
|
||||
<image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" /><text>我知道了</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<AppDialog
|
||||
:visible="conflictHelpVisible"
|
||||
eyebrow="关系校验规则"
|
||||
title="关系冲突说明"
|
||||
message="同一成员不能同时存在两个生父,也不能形成上下代循环。请返回世系树核对原关系后再调整。"
|
||||
@confirm="conflictHelpVisible = false"
|
||||
@close="conflictHelpVisible = false"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, reactive, ref } from 'vue'
|
||||
import AppDialog from '@/components/AppDialog.vue'
|
||||
import ModulePageBackground from '@/components/ModulePageBackground.vue'
|
||||
import PageHeader from '@/components/PageHeader.vue'
|
||||
|
||||
const props = defineProps({ kind: { type: String, required: true } })
|
||||
@@ -124,7 +121,6 @@ const showConflictHelp = () => { conflictHelpVisible.value = true }
|
||||
|
||||
<style scoped lang="scss">
|
||||
.member-form-page { position: relative; min-height: 100vh; overflow: hidden; background: $paper; }
|
||||
.member-form-page__paper { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; pointer-events: none; }
|
||||
.member-form-page__header { position: relative; z-index: 3; }
|
||||
.member-form-panel { position: relative; z-index: 2; width: calc(100% - 32rpx); height: min(640px, calc((100vw - 16px) * 1.48)); margin: 18rpx auto 0; }
|
||||
.member-form-panel__skin { position: absolute; inset: 0; width: 100%; height: 100%; }
|
||||
@@ -148,10 +144,5 @@ const showConflictHelp = () => { conflictHelpVisible.value = true }
|
||||
.member-form-result > .member-form-action { width: 420rpx; max-width: 100%; margin: 32rpx auto 0; }
|
||||
.conflict-actions { display: flex; gap: 14rpx; margin-top: 30rpx; }
|
||||
.conflict-actions .member-form-action { width: calc(50% - 7rpx); margin-top: 0; }
|
||||
.conflict-help { position: fixed; inset: 0; z-index: 20; display: flex; align-items: center; justify-content: center; padding: 32rpx; background: rgba(34, 20, 13, .58); }
|
||||
.conflict-help__card { position: relative; width: min(620rpx, 92vw); height: 390rpx; }
|
||||
.conflict-help__skin { position: absolute; inset: 0; width: 100%; height: 100%; }
|
||||
.conflict-help__content { position: absolute; inset: 62rpx 56rpx 46rpx; text-align: center; }
|
||||
.conflict-help__action { margin-top: 30rpx; }
|
||||
@media (min-width: 400px) { .member-form-panel { width: calc(100% - 48rpx); } }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user