Review changes batch 4 of 6

This commit is contained in:
2026-07-20 06:52:24 +08:00
parent 3e3251a4fc
commit 0d0645a112
12 changed files with 314 additions and 74 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

+304 -74
View File
@@ -16,9 +16,10 @@
src="/static/assets/foundation/transparent/chevron-right.png" src="/static/assets/foundation/transparent/chevron-right.png"
mode="aspectFit" mode="aspectFit"
/> />
<text>返回</text>
</view> </view>
<text class="flow-header__title">{{ isAncestorStep ? "录入首代人物" : "创建家谱" }}</text> <text class="flow-header__title">{{
isAncestorStep ? "录入首代人物" : "创建家谱"
}}</text>
<view class="flow-header__side" /> <view class="flow-header__side" />
</view> </view>
</view> </view>
@@ -27,123 +28,239 @@
<view class="create-flow-panel"> <view class="create-flow-panel">
<image <image
class="create-flow-panel__skin" class="create-flow-panel__skin"
src="/static/assets/modules/genealogy/opaque/g03-create-flow-panel.png" src="/static/assets/modules/genealogy/transparent/g01-empty-panel-frame.png"
mode="scaleToFill" mode="scaleToFill"
/> />
<view v-if="!isAncestorStep" class="create-flow-panel__content"> <view v-if="!isAncestorStep" class="create-flow-panel__content">
<view class="flow-step-label"><text>第一步 · 立谱信息</text></view> <view class="flow-step-label"><text>第一步 · 立谱信息</text></view>
<text class="flow-heading">为家族立一部可传承的谱</text> <text class="flow-heading">为家族立一部可传承的谱</text>
<text class="flow-note">家谱建立后可继续完善名称与访问规则由创建者维护</text> <text class="flow-note"
>家谱建立后可继续完善名称与访问规则由创建者维护</text
>
<view class="flow-fields"> <view class="flow-fields">
<view class="field-row"> <view class="field-row">
<text>姓氏</text> <text>姓氏</text>
<input v-model="createForm.surname" maxlength="4" placeholder="如:汤" placeholder-class="placeholder" @input="clearFieldError('surname')" /> <input
v-model="createForm.surname"
maxlength="4"
placeholder="如:汤"
placeholder-class="placeholder"
@input="clearFieldError('surname')"
/>
</view> </view>
<text v-if="fieldErrors.surname" class="field-error">{{ fieldErrors.surname }}</text> <text v-if="fieldErrors.surname" class="field-error">{{
fieldErrors.surname
}}</text>
<view class="field-row"> <view class="field-row">
<text>谱名</text> <text>谱名</text>
<input v-model="createForm.name" maxlength="24" placeholder="如:汤氏家谱" placeholder-class="placeholder" @input="clearFieldError('name')" /> <input
v-model="createForm.name"
maxlength="24"
placeholder="如:汤氏家谱"
placeholder-class="placeholder"
@input="clearFieldError('name')"
/>
</view> </view>
<text v-if="fieldErrors.name" class="field-error">{{ fieldErrors.name }}</text> <text v-if="fieldErrors.name" class="field-error">{{
fieldErrors.name
}}</text>
<view class="field-row"> <view class="field-row">
<text>堂号</text> <text>堂号</text>
<input v-model="createForm.hall" maxlength="12" placeholder="选填" placeholder-class="placeholder" /> <input
v-model="createForm.hall"
maxlength="12"
placeholder="选填"
placeholder-class="placeholder"
/>
</view> </view>
<view class="field-row"> <view class="field-row">
<text>所在地</text> <text>所在地</text>
<input v-model="createForm.location" maxlength="30" placeholder="请选择或输入" placeholder-class="placeholder" @input="clearFieldError('location')" /> <input
v-model="createForm.location"
maxlength="30"
placeholder="请选择或输入"
placeholder-class="placeholder"
@input="clearFieldError('location')"
/>
</view> </view>
<text v-if="fieldErrors.location" class="field-error">{{ fieldErrors.location }}</text> <text v-if="fieldErrors.location" class="field-error">{{
fieldErrors.location
}}</text>
</view> </view>
<view class="flow-rule"> <view class="flow-rule">
<text class="flow-rule__label">访问规则</text> <text class="flow-rule__label">访问规则</text>
<view class="flow-rule__options"> <view class="flow-rule__options">
<view class="flow-rule__option" :class="{ 'flow-rule__option--active': createForm.visibility === 'MEMBER_ONLY' }" @click="createForm.visibility = 'MEMBER_ONLY'">仅成员可见</view> <view
<view class="flow-rule__option" :class="{ 'flow-rule__option--active': createForm.visibility === 'SEARCHABLE' }" @click="createForm.visibility = 'SEARCHABLE'">可搜索申请</view> class="flow-rule__option"
:class="{
'flow-rule__option--active':
createForm.visibility === 'MEMBER_ONLY',
}"
@click="createForm.visibility = 'MEMBER_ONLY'"
>仅成员可见</view
>
<view
class="flow-rule__option"
:class="{
'flow-rule__option--active':
createForm.visibility === 'SEARCHABLE',
}"
@click="createForm.visibility = 'SEARCHABLE'"
>可搜索申请</view
>
</view> </view>
</view> </view>
<text class="flow-rule__note">保护族人资料创建后可在家谱设置中开放搜索与申请加入</text> <text class="flow-rule__note"
<text v-if="createState === 'error'" class="flow-error">创建样式模拟失败请检查信息后重试</text> >保护族人资料创建后可在家谱设置中开放搜索与申请加入</text
>
<text v-if="createState === 'error'" class="flow-error"
>创建样式模拟失败请检查信息后重试</text
>
<view class="flow-primary-action" hover-class="action-hover" @click="submitCreate"> <view
class="flow-primary-action"
hover-class="action-hover"
@click="submitCreate"
>
<image <image
class="flow-primary-action__skin" class="flow-primary-action__skin"
src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png"
mode="aspectFit" mode="aspectFit"
/> />
<text class="flow-primary-action__copy">{{ createState === 'submitting' ? '正在创建…' : '创建并录入首代' }}</text> <text class="flow-primary-action__copy">{{
createState === "submitting" ? "正在创建…" : "创建并录入首代"
}}</text>
</view> </view>
</view> </view>
<view v-else class="create-flow-panel__content"> <view v-else class="create-flow-panel__content">
<view class="flow-step-label"><text>第二步 · 首代人物</text></view> <view class="flow-step-label"><text>第二步 · 首代人物</text></view>
<text class="flow-heading">家谱从这一位开始</text> <text class="flow-heading">家谱从这一位开始</text>
<text class="flow-note">可先录入姓名世代和简要生平其他资料后续随时补充</text> <text class="flow-note"
>可先录入姓名世代和简要生平其他资料后续随时补充</text
>
<view class="flow-fields"> <view class="flow-fields">
<view class="field-row"> <view class="field-row">
<text>姓名</text> <text>姓名</text>
<input v-model="ancestorForm.personName" maxlength="20" placeholder="请输入首代姓名" placeholder-class="placeholder" @input="clearFieldError('personName')" /> <input
v-model="ancestorForm.personName"
maxlength="20"
placeholder="请输入首代姓名"
placeholder-class="placeholder"
@input="clearFieldError('personName')"
/>
</view> </view>
<text v-if="fieldErrors.personName" class="field-error">{{ fieldErrors.personName }}</text> <text v-if="fieldErrors.personName" class="field-error">{{
fieldErrors.personName
}}</text>
<view class="field-row"> <view class="field-row">
<text>世代</text> <text>世代</text>
<text class="fixed-value">第一世</text> <text class="fixed-value">第一世</text>
</view> </view>
<view class="field-row"> <view class="field-row">
<text>出生日期</text> <text>出生日期</text>
<input v-model="ancestorForm.birthDate" placeholder="如:1940年" placeholder-class="placeholder" /> <input
v-model="ancestorForm.birthDate"
placeholder="如:1940年"
placeholder-class="placeholder"
/>
</view> </view>
</view> </view>
<text v-if="ancestorState === 'error'" class="flow-error">首代人物保存失败请稍后重试</text> <text v-if="ancestorState === 'error'" class="flow-error"
>首代人物保存失败请稍后重试</text
>
<view class="intro-field"> <view class="intro-field">
<text>生平简述</text> <text>生平简述</text>
<textarea v-model="ancestorForm.introduction" maxlength="200" placeholder="可选,记录家训、迁徙或重要经历" placeholder-class="placeholder" /> <textarea
v-model="ancestorForm.introduction"
maxlength="200"
placeholder="可选,记录家训、迁徙或重要经历"
placeholder-class="placeholder"
/>
</view> </view>
<view class="flow-primary-action" hover-class="action-hover" @click="submitAncestor"> <view
class="flow-primary-action"
hover-class="action-hover"
@click="submitAncestor"
>
<image <image
class="flow-primary-action__skin" class="flow-primary-action__skin"
src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png"
mode="aspectFit" mode="aspectFit"
/> />
<text class="flow-primary-action__copy">{{ ancestorState === 'submitting' ? '正在保存…' : '保存并进入家谱' }}</text> <text class="flow-primary-action__copy">{{
ancestorState === "submitting" ? "正在保存…" : "保存并进入家谱"
}}</text>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<view v-if="duplicateReminderVisible" class="duplicate-reminder-layer" @click="closeDuplicateReminder"> <view
v-if="duplicateReminderVisible"
class="duplicate-reminder-layer"
@click="closeDuplicateReminder"
>
<view class="duplicate-reminder" @click.stop> <view class="duplicate-reminder" @click.stop>
<image class="duplicate-reminder__skin" src="/static/assets/modules/auth/transparent/a01-scroll-dialog-v3.png" mode="aspectFit" /> <image
class="duplicate-reminder__skin"
src="/static/assets/modules/auth/transparent/a01-scroll-dialog-v3.png"
mode="aspectFit"
/>
<view class="duplicate-reminder__content"> <view class="duplicate-reminder__content">
<text class="duplicate-reminder__title">先确认是否已有家谱</text> <text class="duplicate-reminder__title">先确认是否已有家谱</text>
<text class="duplicate-reminder__copy">同一家族可能已经建谱建议先搜索谱名地区和堂号避免重复创建</text> <text class="duplicate-reminder__copy"
<view class="duplicate-reminder__search" @click="searchExistingGenealogy"> >同一家族可能已经建谱建议先搜索谱名地区和堂号避免重复创建</text
<image src="/static/assets/foundation/transparent/a01-scroll-secondary-v3.png" mode="aspectFit" /> >
<view
class="duplicate-reminder__search"
@click="searchExistingGenealogy"
>
<image
src="/static/assets/foundation/transparent/a01-scroll-secondary-v3.png"
mode="aspectFit"
/>
<text>先搜索已有家谱</text> <text>先搜索已有家谱</text>
</view> </view>
<view class="duplicate-reminder__confirm" @click="confirmCreate"> <view class="duplicate-reminder__confirm" @click="confirmCreate">
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="aspectFit" /> <image
src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png"
mode="aspectFit"
/>
<text>确认没有继续创建</text> <text>确认没有继续创建</text>
</view> </view>
<view class="duplicate-reminder__cancel" @click="closeDuplicateReminder">返回修改</view> <view
class="duplicate-reminder__cancel"
@click="closeDuplicateReminder"
>返回修改</view
>
</view> </view>
</view> </view>
</view> </view>
<view v-if="ancestorState === 'success'" class="flow-success-layer"> <view v-if="ancestorState === 'success'" class="flow-success-layer">
<view class="flow-success-dialog"> <view class="flow-success-dialog">
<image class="flow-success-dialog__skin" src="/static/assets/modules/auth/transparent/a01-scroll-dialog-v3.png" mode="aspectFit" /> <image
class="flow-success-dialog__skin"
src="/static/assets/modules/auth/transparent/a01-scroll-dialog-v3.png"
mode="aspectFit"
/>
<view class="flow-success-dialog__content"> <view class="flow-success-dialog__content">
<text class="flow-success-dialog__title">家谱创建完成</text> <text class="flow-success-dialog__title">家谱创建完成</text>
<text class="flow-success-dialog__copy">首代人物已保存接下来进入家谱总览继续完善资料</text> <text class="flow-success-dialog__copy"
>首代人物已保存接下来进入家谱总览继续完善资料</text
>
<view class="flow-success-dialog__action" @click="enterOverview"> <view class="flow-success-dialog__action" @click="enterOverview">
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="aspectFit" /> <image
src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png"
mode="aspectFit"
/>
<text>进入家谱总览</text> <text>进入家谱总览</text>
</view> </view>
</view> </view>
@@ -163,7 +280,12 @@ const isSubmitting = ref(false);
const createState = ref("form"); const createState = ref("form");
const ancestorState = ref("form"); const ancestorState = ref("form");
const duplicateReminderVisible = ref(false); const duplicateReminderVisible = ref(false);
const fieldErrors = reactive({ surname: "", name: "", location: "", personName: "" }); const fieldErrors = reactive({
surname: "",
name: "",
location: "",
personName: "",
});
let submitTimer = null; let submitTimer = null;
const createForm = reactive({ const createForm = reactive({
surname: "", surname: "",
@@ -198,9 +320,12 @@ const syncFlowFromRoute = () => {
const isAncestorRoute = query.get const isAncestorRoute = query.get
? query.get("step") === "ancestor" ? query.get("step") === "ancestor"
: query.step === "ancestor"; : query.step === "ancestor";
const routeGenealogyId = query.get ? query.get("genealogyId") : query.genealogyId; const routeGenealogyId = query.get
? query.get("genealogyId")
: query.genealogyId;
currentStep.value = isAncestorRoute ? "ancestor" : "create"; currentStep.value = isAncestorRoute ? "ancestor" : "create";
genealogyId.value = routeGenealogyId || (isAncestorStep.value ? "local-created-genealogy" : ""); genealogyId.value =
routeGenealogyId || (isAncestorStep.value ? "local-created-genealogy" : "");
}; };
onLoad(() => { onLoad(() => {
@@ -233,7 +358,9 @@ const goBack = () => {
uni.navigateBack(); uni.navigateBack();
}; };
const clearFieldError = (field) => { fieldErrors[field] = ""; }; const clearFieldError = (field) => {
fieldErrors[field] = "";
};
const validateCreateForm = () => { const validateCreateForm = () => {
fieldErrors.surname = createForm.surname.trim() ? "" : "请填写姓氏"; fieldErrors.surname = createForm.surname.trim() ? "" : "请填写姓氏";
@@ -249,8 +376,11 @@ const submitCreate = () => {
duplicateReminderVisible.value = true; duplicateReminderVisible.value = true;
}; };
const closeDuplicateReminder = () => { duplicateReminderVisible.value = false; }; const closeDuplicateReminder = () => {
const searchExistingGenealogy = () => uni.navigateTo({ url: "/pages/genealogy/g06-search-genealogies" }); duplicateReminderVisible.value = false;
};
const searchExistingGenealogy = () =>
uni.navigateTo({ url: "/pages/genealogy/g06-search-genealogies" });
const confirmCreate = () => { const confirmCreate = () => {
closeDuplicateReminder(); closeDuplicateReminder();
isSubmitting.value = true; isSubmitting.value = true;
@@ -262,7 +392,9 @@ const confirmCreate = () => {
return; return;
} }
const createdId = "local-created-genealogy"; const createdId = "local-created-genealogy";
uni.redirectTo({ url: `/pages/genealogy/g03-create-genealogy?step=ancestor&genealogyId=${createdId}` }); uni.redirectTo({
url: `/pages/genealogy/g03-create-genealogy?step=ancestor&genealogyId=${createdId}`,
});
}, 320); }, 320);
}; };
@@ -281,11 +413,15 @@ const submitAncestor = () => {
ancestorState.value = "submitting"; ancestorState.value = "submitting";
submitTimer = setTimeout(() => { submitTimer = setTimeout(() => {
isSubmitting.value = false; isSubmitting.value = false;
ancestorState.value = ancestorForm.personName.trim() === "失败" ? "error" : "success"; ancestorState.value =
ancestorForm.personName.trim() === "失败" ? "error" : "success";
}, 320); }, 320);
}; };
const enterOverview = () => uni.redirectTo({ url: `/pages/genealogy/g05-genealogy-overview?genealogyId=${genealogyId.value}` }); const enterOverview = () =>
uni.redirectTo({
url: `/pages/genealogy/g05-genealogy-overview?genealogyId=${genealogyId.value}`,
});
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@@ -325,20 +461,13 @@ const enterOverview = () => uni.redirectTo({ url: `/pages/genealogy/g05-genealog
.flow-header__back, .flow-header__back,
.flow-header__side { .flow-header__side {
display: flex; display: flex;
width: 130rpx; width: 72rpx;
align-items: center; align-items: center;
} }
.flow-header__back {
color: #fff3d9;
font-family: "STKaiti", "KaiTi", serif;
font-size: 27rpx;
}
.flow-header__back-icon { .flow-header__back-icon {
width: 30rpx; width: 34rpx;
height: 30rpx; height: 34rpx;
margin-right: 4rpx;
transform: rotate(180deg); transform: rotate(180deg);
} }
@@ -403,7 +532,7 @@ const enterOverview = () => uni.redirectTo({ url: `/pages/genealogy/g05-genealog
.flow-rule__note { .flow-rule__note {
display: block; display: block;
color: #786654; color: #786654;
font-size: 23rpx; font-size: 25rpx;
line-height: 1.65; line-height: 1.65;
} }
@@ -442,7 +571,14 @@ const enterOverview = () => uni.redirectTo({ url: `/pages/genealogy/g05-genealog
.placeholder { .placeholder {
color: #b7aa97; color: #b7aa97;
} }
.field-error { display: block; margin-top: 3rpx; color: $brand-red; font-size: 20rpx; text-align: right; } .field-error {
display: block;
margin-top: 3rpx;
color: $brand-red;
font-size: 24rpx;
line-height: 34rpx;
text-align: right;
}
.fixed-value { .fixed-value {
color: #a33b2b !important; color: #a33b2b !important;
@@ -462,14 +598,34 @@ const enterOverview = () => uni.redirectTo({ url: `/pages/genealogy/g05-genealog
font-weight: 700; font-weight: 700;
} }
.flow-rule__options { display: flex; gap: 12rpx; } .flow-rule__options {
.flow-rule__option { display: flex; min-height: 54rpx; align-items: center; padding: 0 10rpx; color: #786654; font-size: 21rpx; } display: flex;
.flow-rule__option--active { color: $brand-red; font-weight: 700; } gap: 12rpx;
}
.flow-rule__option {
display: flex;
min-height: 54rpx;
align-items: center;
padding: 0 10rpx;
color: #786654;
font-size: 23rpx;
}
.flow-rule__option--active {
color: $brand-red;
font-weight: 700;
}
.flow-rule__note { .flow-rule__note {
margin-top: 8rpx; margin-top: 8rpx;
} }
.flow-error { display: block; margin-top: 10rpx; color: $brand-red; font-size: 21rpx; text-align: center; } .flow-error {
display: block;
margin-top: 10rpx;
color: $brand-red;
font-size: 25rpx;
line-height: 36rpx;
text-align: center;
}
.intro-field { .intro-field {
margin-top: 18rpx; margin-top: 18rpx;
@@ -525,29 +681,103 @@ const enterOverview = () => uni.redirectTo({ url: `/pages/genealogy/g05-genealog
opacity: 0.82; opacity: 0.82;
} }
.duplicate-reminder-layer, .duplicate-reminder-layer,
.flow-success-layer { position: fixed; z-index: 30; inset: 0; display: flex; align-items: center; justify-content: center; box-sizing: border-box; padding: 42rpx; background: rgba(34, 20, 12, .6); } .flow-success-layer {
position: fixed;
z-index: 30;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
padding: 42rpx;
background: rgba(34, 20, 12, 0.6);
}
.duplicate-reminder, .duplicate-reminder,
.flow-success-dialog { position: relative; width: 100%; max-width: 670rpx; min-height: 650rpx; } .flow-success-dialog {
position: relative;
width: 100%;
max-width: 670rpx;
min-height: 650rpx;
}
.duplicate-reminder__skin, .duplicate-reminder__skin,
.flow-success-dialog__skin { position: absolute; inset: 0; width: 100%; height: 100%; } .flow-success-dialog__skin {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
.duplicate-reminder__content, .duplicate-reminder__content,
.flow-success-dialog__content { position: relative; z-index: 1; display: flex; min-height: 650rpx; flex-direction: column; align-items: center; box-sizing: border-box; padding: 92rpx 64rpx 56rpx; text-align: center; } .flow-success-dialog__content {
position: relative;
z-index: 1;
display: flex;
min-height: 650rpx;
flex-direction: column;
align-items: center;
box-sizing: border-box;
padding: 92rpx 64rpx 56rpx;
text-align: center;
}
.duplicate-reminder__title, .duplicate-reminder__title,
.flow-success-dialog__title { color: $ink; font-family: "STKaiti", "KaiTi", serif; font-size: 39rpx; font-weight: 700; } .flow-success-dialog__title {
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 39rpx;
font-weight: 700;
}
.duplicate-reminder__copy, .duplicate-reminder__copy,
.flow-success-dialog__copy { margin-top: 24rpx; color: $ink-muted; font-size: 24rpx; line-height: 40rpx; } .flow-success-dialog__copy {
margin-top: 24rpx;
color: $ink-muted;
font-size: 24rpx;
line-height: 40rpx;
}
.duplicate-reminder__search, .duplicate-reminder__search,
.duplicate-reminder__confirm, .duplicate-reminder__confirm,
.flow-success-dialog__action { position: relative; display: flex; width: 100%; height: 92rpx; align-items: center; justify-content: center; overflow: hidden; } .flow-success-dialog__action {
.duplicate-reminder__search { margin-top: 38rpx; } position: relative;
.duplicate-reminder__confirm { margin-top: 14rpx; } display: flex;
width: 100%;
height: 92rpx;
align-items: center;
justify-content: center;
overflow: hidden;
}
.duplicate-reminder__search {
margin-top: 38rpx;
}
.duplicate-reminder__confirm {
margin-top: 14rpx;
}
.duplicate-reminder__search image, .duplicate-reminder__search image,
.duplicate-reminder__confirm image, .duplicate-reminder__confirm image,
.flow-success-dialog__action image { position: absolute; inset: 0; width: 100%; height: 100%; } .flow-success-dialog__action image {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
.duplicate-reminder__search text, .duplicate-reminder__search text,
.duplicate-reminder__confirm text, .duplicate-reminder__confirm text,
.flow-success-dialog__action text { position: relative; z-index: 1; color: #fff9ec; font-size: 25rpx; font-weight: 700; } .flow-success-dialog__action text {
.duplicate-reminder__search text { color: #7b4e24; } position: relative;
.duplicate-reminder__cancel { display: flex; min-height: 68rpx; align-items: center; margin-top: auto; color: $ink-muted; font-size: 23rpx; } z-index: 1;
.flow-success-dialog__action { margin-top: 44rpx; } color: #fff9ec;
font-size: 25rpx;
font-weight: 700;
}
.duplicate-reminder__search text {
color: #7b4e24;
}
.duplicate-reminder__cancel {
display: flex;
min-height: 68rpx;
align-items: center;
margin-top: auto;
color: $ink-muted;
font-size: 23rpx;
}
.flow-success-dialog__action {
margin-top: 44rpx;
}
</style> </style>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

+10
View File
@@ -0,0 +1,10 @@
$ErrorActionPreference = 'Stop'
$root = Split-Path -Parent $PSScriptRoot
$capture = Get-Content -LiteralPath (Join-Path $root 'scripts/capture-chrome-page.js') -Raw -Encoding utf8
foreach ($required in @('prepareG09State', 'g09-withdraw-dialog', 'g09-withdrawn')) {
if ($capture -notmatch [regex]::Escape($required)) { throw "G09 capture state missing: $required" }
}
if ($capture -notmatch 'await prepareG09State\(send, action\)') { throw 'Capture runner does not prepare G09 states' }
Write-Output 'CAPTURE-G09-STATES-CONTRACT PASS'