diff --git a/src/pages-aigc/useTemplate/components/GeneratingProgressPanel/index.vue b/src/pages-aigc/useTemplate/components/GeneratingProgressPanel/index.vue new file mode 100644 index 0000000..6d352c4 --- /dev/null +++ b/src/pages-aigc/useTemplate/components/GeneratingProgressPanel/index.vue @@ -0,0 +1,56 @@ + + + + + diff --git a/src/pages-aigc/useTemplate/components/GeneratingProgressPanel/styles/index.scss b/src/pages-aigc/useTemplate/components/GeneratingProgressPanel/styles/index.scss new file mode 100644 index 0000000..9911007 --- /dev/null +++ b/src/pages-aigc/useTemplate/components/GeneratingProgressPanel/styles/index.scss @@ -0,0 +1,87 @@ +.generating-progress-panel { + margin-top: 20px; +} + +.generating-progress-row { + height: 18px; + display: grid; + grid-template-columns: minmax(0, 1fr) 34px; + align-items: center; + gap: 10px; +} + +.generating-progress-track { + width: 100%; + height: 12px; + overflow: hidden; + border-radius: 999px; + background: rgba(255, 255, 255, 0.78); +} + +.generating-progress-fill { + height: 100%; + min-width: 24px; + border-radius: 999px; + background: linear-gradient(90deg, #20cf75 0%, #f2d646 100%); +} + +.generating-progress-text { + color: #061e34; + font-size: 15px; + line-height: 18px; + font-weight: 900; + text-align: right; + white-space: nowrap; +} + +.generating-step-list { + display: flex; + flex-direction: column; + gap: 10px; + margin-top: 16px; +} + +.generating-step-item { + height: 40px; + display: flex; + align-items: center; + gap: 10px; + padding: 0 12px; + border-radius: 14px; + background: rgba(255, 255, 255, 0.72); + box-sizing: border-box; +} + +.generating-step-dot { + flex: 0 0 18px; + width: 18px; + height: 18px; + border: 2px solid #d6e8f4; + border-radius: 50%; + background: rgba(255, 255, 255, 0.7); + box-sizing: border-box; +} + +.generating-step-label { + min-width: 0; + overflow: hidden; + color: #6c7e96; + font-size: 13px; + line-height: 18px; + font-weight: 900; + text-overflow: ellipsis; + white-space: nowrap; +} + +.generating-freeze-text { + display: block; + overflow: hidden; + margin: 18px 14px 0; + color: #7b8da4; + font-size: 12px; + line-height: 18px; + font-weight: 800; + text-align: center; + text-overflow: ellipsis; + white-space: nowrap; +} diff --git a/src/pages-aigc/useTemplate/components/PointInsufficientDialog/index.vue b/src/pages-aigc/useTemplate/components/PointInsufficientDialog/index.vue new file mode 100644 index 0000000..7918103 --- /dev/null +++ b/src/pages-aigc/useTemplate/components/PointInsufficientDialog/index.vue @@ -0,0 +1,65 @@ + + + + + diff --git a/src/pages-aigc/useTemplate/components/PointInsufficientDialog/styles/index.scss b/src/pages-aigc/useTemplate/components/PointInsufficientDialog/styles/index.scss new file mode 100644 index 0000000..5217bfd --- /dev/null +++ b/src/pages-aigc/useTemplate/components/PointInsufficientDialog/styles/index.scss @@ -0,0 +1,70 @@ +.point-dialog { + width: 318px; + max-width: calc(100vw - 56px); + min-height: 220px; + padding: 29px 24px 22px; + border: 1px solid rgba(20, 143, 255, 0.8); + border-radius: 20px; + background: #dceeff; + box-shadow: 0 18px 38px rgba(8, 28, 44, 0.22); + box-sizing: border-box; +} + +.point-dialog-title { + display: block; + color: #102942; + font-size: 22px; + line-height: 29px; + font-weight: 900; + text-align: center; +} + +.point-dialog-desc { + display: block; + overflow: hidden; + margin: 15px auto 0; + max-width: 228px; + color: #506985; + font-size: 14px; + line-height: 22px; + font-weight: 800; + text-align: center; +} + +.point-dialog-actions { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 18px; + margin-top: 28px; +} + +.point-dialog-button { + min-width: 0; + height: 54px; + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; + border-radius: 999px; + font-size: 16px; + line-height: 22px; + font-weight: 900; + text-overflow: ellipsis; + white-space: nowrap; + box-sizing: border-box; +} + +.point-dialog-button.is-cancel { + border: 1px solid rgba(124, 168, 207, 0.28); + background: rgba(255, 255, 255, 0.14); + color: #102942; +} + +.point-dialog-button.is-primary { + background: #061e34; + color: #ffffff; +} + +.point-dialog-button.is-pressed { + opacity: 0.86; +} diff --git a/src/pages-aigc/useTemplate/useTemplate.vue b/src/pages-aigc/useTemplate/useTemplate.vue index 6b4b6d5..c83a3b5 100644 --- a/src/pages-aigc/useTemplate/useTemplate.vue +++ b/src/pages-aigc/useTemplate/useTemplate.vue @@ -19,6 +19,11 @@ @generate="handleGenerate" @recharge="handleRecharge" /> + @@ -67,9 +79,11 @@ import AigcTopBar from "@/pages-aigc/components/AigcTopBar/index.vue"; import { aigcTemplates } from "@/pages-aigc/home/data/templates.js"; import guideAvatar from "./assets/xiaoqi-avatar.png"; import GenerateConfirmPanel from "./components/GenerateConfirmPanel/index.vue"; +import GeneratingProgressPanel from "./components/GeneratingProgressPanel/index.vue"; import PhotoConfirmDrawer from "./components/PhotoConfirmDrawer/index.vue"; import PhotoGuidePanel from "./components/PhotoGuidePanel/index.vue"; import PhotoPickDrawer from "./components/PhotoPickDrawer/index.vue"; +import PointInsufficientDialog from "./components/PointInsufficientDialog/index.vue"; import TemplateVersionHero from "./components/TemplateVersionHero/index.vue"; import VersionOptionList from "./components/VersionOptionList/index.vue"; import { negativeExamples, positiveExamples } from "./data/photoGuideExamples.js"; @@ -79,6 +93,7 @@ const pointBalance = ref(300); const templateId = ref(""); const selectedVersion = ref("image"); const currentStep = ref("version"); +const pointDialogVisible = ref(false); const currentTemplate = computed(() => { return aigcTemplates.find((item) => item.id === templateId.value) || aigcTemplates[0] || {}; @@ -150,7 +165,24 @@ const handleConfirmPhoto = () => { }; const handleGenerate = () => { - showPlaceholderToast("开始生成"); + const cost = Number(currentVersion.value.cost) || 0; + const balance = Number(pointBalance.value) || 0; + + if (balance < cost) { + pointDialogVisible.value = true; + return; + } + + currentStep.value = "generating"; +}; + +const handleClosePointDialog = () => { + pointDialogVisible.value = false; +}; + +const handlePointRecharge = () => { + pointDialogVisible.value = false; + handleRecharge(); };