修改:京东下单页面样式与引导图、编辑购买交互优化
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/prod Build is passing

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
LinzmandCursor committed 2026-11-10 17:51:23 +08:00
1 parent 789d4f106c
commit 2f9d443a6a
6 files changed
+371 -256

No files matched your search

+68 -74
View File
@@ -27,19 +27,14 @@
</div>
<div v-else-if="msg.type === 'case'" class="msg__bubble msg__bubble--case">
<p class="msg__case-intro">{{ config.messages.caseIntro }}</p>
<div class="msg__case-grid">
<figure
v-for="(item, idx) in caseItems"
:key="item.label"
class="msg__case-item"
>
<div class="msg__case-thumb">
<img :src="item.src" :alt="item.label" @click="previewImages(caseItems.map((c) => c.src), idx)" />
</div>
<figcaption>{{ item.label }}</figcaption>
</figure>
</div>
<button
class="msg__guide"
type="button"
:aria-label="config.messages.caseIntro"
@click="previewImages([config.images.guide], 0)"
>
<img class="msg__guide-img" :src="config.images.guide" :alt="config.messages.caseIntro" />
</button>
</div>
<div
@@ -65,11 +60,10 @@
:image="msg.image"
:meta="msg.meta"
:editing="editingResultId === msg.id"
:show-buy="editingResultId !== msg.id"
:view-label="config.messages.view"
:edit-label="config.messages.edit"
:exit-edit-label="config.messages.exitEdit"
:buy-label="config.messages.buyNow"
:buy-disabled-tip="config.messages.buyDisabledTip"
@view="previewImages([msg.image], 0)"
@edit="(payload) => enterEdit(msg.id, payload?.sourceRect)"
@exit-edit="exitEdit"
@@ -91,6 +85,9 @@
:placeholder="config.messages.placeholder"
:placeholder-need-photo="config.messages.placeholderNeedPhoto"
:placeholder-editing="config.messages.placeholderEditing"
:custom-text-label="titleSpec?.label || config.messages.customTextLabel"
:custom-text-placeholder="titleSpec?.placeholder || config.messages.customTextPlaceholder"
:custom-text-max="titleSpec?.max || config.messages.customTextMax"
:preview-url="pendingPreview"
:tags="composerTags"
:editing="isEditing"
@@ -189,12 +186,6 @@ function formatTime(date = new Date()) {
return `${h}:${m}`
}
const caseItems = [
{ label: config.messages.caseLabels[0], src: config.images.caseOriginal },
{ label: config.messages.caseLabels[1], src: config.images.caseEffect },
{ label: config.messages.caseLabels[2], src: config.images.caseScene },
]
/**
* 剩余次数:
* - 首屏用接口 remain_count 打底
@@ -814,6 +805,7 @@ async function startGenerate(opts: {
/** 编辑效果图:直接 submit,传 image_id,不走 url/confirm */
imageId?: string
sceneProp?: string
customText?: string
}) {
if (remainCount.value <= 0) {
showToast(config.messages.noRemain)
@@ -877,13 +869,14 @@ async function startGenerate(opts: {
}
const sceneProp = String(opts.sceneProp || '').trim()
const customText = String(opts.customText || '').trim()
const task = await jingdongApi.submitImageGen({
session_id: sid,
...(isEdit ? { image_id: editImageId } : { upload_id: uploadId }),
prompt: opts.userText,
mode: opts.mode,
scene_prop: sceneProp,
custom_text: '',
custom_text: customText,
})
let taskId = task.task_id
if (!taskId) throw new Error('提交生成失败')
@@ -940,13 +933,23 @@ function onSend() {
if (titleSpec.value && !productTitle.value.trim()) {
titleInvalid.value = true
showToast(config.messages.needProductTitle(titleSpec.value.label))
showToast(
config.messages.needProductTitle(
titleSpec.value.label || config.messages.customTextLabel,
),
)
return
}
titleInvalid.value = false
const text = draft.value.trim()
const sceneProp = resolveScenePropFromOrder(orderStat.value, productTitle.value)
// 必须在 reset 前取出:场景道具走 scene_prop,其余走 custom_text
const titleValue = productTitle.value.trim()
const isPropsTitle = titleSpec.value?.mode === 'props'
const sceneProp = isPropsTitle
? resolveScenePropFromOrder(orderStat.value, titleValue)
: ''
const customText = isPropsTitle ? '' : titleValue
if (isEditing.value) {
if (!text) {
@@ -976,6 +979,7 @@ function onSend() {
mode: 'edit',
imageId,
sceneProp,
customText,
})
return
}
@@ -1018,6 +1022,7 @@ function onSend() {
mode: 'generate',
uploadId,
sceneProp,
customText,
})
}
@@ -1158,7 +1163,10 @@ onBeforeUnmount(() => {
<style scoped lang="scss">
.jd-page {
--jd-primary: #3a8e4d;
--jd-bg: #f5f5f5;
--jd-bg: #ffffff;
--jd-avatar: 36px;
--jd-avatar-gap: 10px;
--jd-avatar-slot: calc(var(--jd-avatar) + var(--jd-avatar-gap));
display: flex;
flex-direction: column;
height: 100vh;
@@ -1198,8 +1206,8 @@ onBeforeUnmount(() => {
}
.msg__avatar {
width: 36px;
height: 36px;
width: var(--jd-avatar);
height: var(--jd-avatar);
flex-shrink: 0;
border-radius: 8px;
overflow: hidden;
@@ -1227,7 +1235,8 @@ onBeforeUnmount(() => {
}
.msg__body {
max-width: calc(100% - 52px);
/* 左侧头像占位后,右侧再留一个头像宽度,与用户侧对称 */
max-width: calc(100% - var(--jd-avatar-slot) - var(--jd-avatar));
min-width: 0;
}
@@ -1235,11 +1244,11 @@ onBeforeUnmount(() => {
display: flex;
flex-direction: column;
align-items: flex-end;
max-width: min(268px, calc(100% - 52px));
max-width: min(268px, calc(100% - var(--jd-avatar-slot)));
}
.msg.is-case .msg__body {
max-width: calc(100% - 46px);
max-width: calc(100% - var(--jd-avatar-slot) - var(--jd-avatar));
}
.msg__bubble {
@@ -1259,6 +1268,8 @@ onBeforeUnmount(() => {
.msg:not(.is-user) .msg__bubble {
border-radius: 4px 16px 16px 16px;
border: 1px solid #e6e6e6;
box-sizing: border-box;
}
.msg__bubble--user {
@@ -1303,62 +1314,45 @@ onBeforeUnmount(() => {
}
.msg__bubble--case {
padding: 12px;
}
.msg__case-intro {
margin: 0 0 10px;
font-size: 14px;
line-height: 1.5;
color: #222;
}
.msg__case-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
}
.msg__case-item {
margin: 0;
min-width: 0;
figcaption {
margin-top: 6px;
text-align: center;
font-size: 12px;
color: #999;
line-height: 1.2;
}
}
.msg__case-thumb {
width: 100%;
aspect-ratio: 1 / 1;
border-radius: 10px;
padding: 0;
overflow: hidden;
background: #f0f0f0;
background: #ffffff;
box-shadow: none;
}
img {
display: block;
width: 100%;
height: 200%;
object-fit: contain;
object-position: center top;
cursor: pointer;
}
.msg__guide {
display: block;
width: 100%;
margin: 0;
padding: 0;
border: 0;
background: transparent;
cursor: pointer;
border-radius: 16px;
overflow: hidden;
}
.msg__guide-img {
display: block;
width: 100%;
height: auto;
vertical-align: top;
}
.msg__bubble--generating {
padding: 0;
background: transparent;
background: #ffffff;
box-shadow: none;
overflow: hidden;
width: 60vw;
max-width: 100%;
box-sizing: border-box;
}
.msg__bubble--result {
padding: 10px;
width: min(280px, 72vw);
/* 效果图最大占整屏宽度 60% */
width: 60vw;
max-width: 100%;
box-sizing: border-box;
}