恢复修改的数据
This commit is contained in:
@@ -1,131 +1,143 @@
|
||||
<script setup lang="ts">
|
||||
// 需求提报(单页三段卡片 + 底部固定操作条,数据全部走真实接口)
|
||||
// 页面 → store → api;页面不直接 import api
|
||||
import { onMounted } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { AppButton, StepForm } from '@/components'
|
||||
import { useDemandStore } from '@/stores/modules/demand'
|
||||
import { useUserStore } from '@/stores/modules/user'
|
||||
import type { BusinessType } from '@/types/api'
|
||||
import type { Demand } from '@/types/business/demand'
|
||||
import DemandStep1Business from './cpns/DemandStep1Business.vue'
|
||||
import DemandStep2Info from './cpns/DemandStep2Info.vue'
|
||||
import DemandStep3Confirm from './cpns/DemandStep3Confirm.vue'
|
||||
import type { Demand, DemandAttachment } from '@/types/business/demand'
|
||||
import DemandActionBar from './cpns/DemandActionBar.vue'
|
||||
import DemandBizTypes from './cpns/DemandBizTypes.vue'
|
||||
import DemandConfirmForm from './cpns/DemandConfirmForm.vue'
|
||||
import DemandInfoForm from './cpns/DemandInfoForm.vue'
|
||||
|
||||
const STEP_TITLES = ['选择业务类型', '填写需求信息', '确认信息并补充备注']
|
||||
|
||||
const router = useRouter()
|
||||
const demandStore = useDemandStore()
|
||||
const userStore = useUserStore()
|
||||
const { form, step, loading } = storeToRefs(demandStore)
|
||||
const {
|
||||
form,
|
||||
bizTypeOptions,
|
||||
budgetOptions,
|
||||
loading,
|
||||
saving,
|
||||
submitting,
|
||||
uploading,
|
||||
} = storeToRefs(demandStore)
|
||||
|
||||
function onSelectBusiness(type: BusinessType): void {
|
||||
demandStore.patchForm({ businessType: type })
|
||||
function onBizType(value: string): void {
|
||||
demandStore.patchForm({ bizType: value })
|
||||
}
|
||||
|
||||
function onUpdateDemand(partial: Partial<Demand>): void {
|
||||
function onUpdate(partial: Partial<Demand>): void {
|
||||
demandStore.patchForm(partial)
|
||||
}
|
||||
|
||||
function onUpload(file: File): void {
|
||||
demandStore.addAttachment(file)
|
||||
void demandStore.addAttachment(file)
|
||||
}
|
||||
|
||||
function onRemoveFile(file: Demand['attachments'][number]): void {
|
||||
function onRemoveFile(file: DemandAttachment): void {
|
||||
demandStore.removeAttachment(file)
|
||||
}
|
||||
|
||||
function goPrev(): void {
|
||||
if (step.value > 1) demandStore.setStep(step.value - 1)
|
||||
}
|
||||
|
||||
function goNext(): void {
|
||||
if (step.value < 3) demandStore.setStep(step.value + 1)
|
||||
}
|
||||
|
||||
async function onSubmit(): Promise<void> {
|
||||
const ok = await demandStore.submit()
|
||||
if (ok && userStore.isLoggedIn) {
|
||||
void router.push('/project')
|
||||
}
|
||||
}
|
||||
|
||||
function onSaveDraft(): void {
|
||||
void demandStore.saveDraft()
|
||||
}
|
||||
|
||||
function onReset(): void {
|
||||
demandStore.reset()
|
||||
void demandStore.reset()
|
||||
}
|
||||
|
||||
async function onSubmit(): Promise<void> {
|
||||
await demandStore.submit()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
void demandStore.loadDraft()
|
||||
void demandStore.init()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="demand">
|
||||
<header class="demand__head">
|
||||
<h1 class="demand__title">
|
||||
需求提报
|
||||
</h1>
|
||||
<p class="demand__subtitle text-secondary">
|
||||
填写您的需求信息,专业顾问将快速与您联系
|
||||
</p>
|
||||
</header>
|
||||
<div class="demand-page">
|
||||
<div class="container demand" :class="{ 'is-loading': loading }">
|
||||
<header class="demand__head">
|
||||
<h1 class="demand__title">
|
||||
需求提报
|
||||
</h1>
|
||||
<p class="demand__subtitle">
|
||||
填写您的需求信息,专业顾问将快速与您联系
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<StepForm :titles="STEP_TITLES" :current="step - 1">
|
||||
<DemandStep1Business
|
||||
v-if="step === 1"
|
||||
:demand="form"
|
||||
@select="onSelectBusiness"
|
||||
/>
|
||||
<DemandStep2Info
|
||||
v-else-if="step === 2"
|
||||
:demand="form"
|
||||
@update:demand="onUpdateDemand"
|
||||
@upload="onUpload"
|
||||
@remove-file="onRemoveFile"
|
||||
/>
|
||||
<DemandStep3Confirm
|
||||
v-else
|
||||
:demand="form"
|
||||
@update:demand="onUpdateDemand"
|
||||
/>
|
||||
</StepForm>
|
||||
<!-- ① 选择业务类型 -->
|
||||
<section class="demand__card">
|
||||
<h2 class="demand__section">
|
||||
<span class="demand__index">1</span>
|
||||
选择业务类型<span class="demand__required">*</span>
|
||||
</h2>
|
||||
<DemandBizTypes
|
||||
:options="bizTypeOptions"
|
||||
:model-value="form.bizType"
|
||||
@update:model-value="onBizType"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<div class="demand__nav">
|
||||
<AppButton :disabled="step === 1 || loading" @click="goPrev">
|
||||
上一步
|
||||
</AppButton>
|
||||
<AppButton v-if="step < 3" type="primary" :disabled="loading" @click="goNext">
|
||||
下一步
|
||||
</AppButton>
|
||||
<!-- ② 填写需求信息 -->
|
||||
<section class="demand__card">
|
||||
<h2 class="demand__section">
|
||||
<span class="demand__index">2</span>
|
||||
填写需求信息<span class="demand__required">*</span>
|
||||
</h2>
|
||||
<DemandInfoForm
|
||||
:demand="form"
|
||||
:budget-options="budgetOptions"
|
||||
:uploading="uploading"
|
||||
@update="onUpdate"
|
||||
@upload="onUpload"
|
||||
@remove-file="onRemoveFile"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<!-- ③ 确认信息并补充备注 -->
|
||||
<section class="demand__card">
|
||||
<h2 class="demand__section">
|
||||
<span class="demand__index">3</span>
|
||||
确认信息并补充备注
|
||||
</h2>
|
||||
<DemandConfirmForm
|
||||
:demand="form"
|
||||
@update="onUpdate"
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="demand__actions">
|
||||
<AppButton type="primary" size="lg" :loading="loading" @click="onSubmit">
|
||||
立即提报
|
||||
</AppButton>
|
||||
<AppButton size="lg" :disabled="loading" @click="onSaveDraft">
|
||||
保存草稿
|
||||
</AppButton>
|
||||
<AppButton size="lg" :disabled="loading" @click="onReset">
|
||||
重置
|
||||
</AppButton>
|
||||
</div>
|
||||
<DemandActionBar
|
||||
:saving="saving"
|
||||
:submitting="submitting"
|
||||
@save-draft="onSaveDraft"
|
||||
@reset="onReset"
|
||||
@submit="onSubmit"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.demand {
|
||||
.flex(column, flex-start);
|
||||
gap: @spacing-base;
|
||||
padding-top: @spacing-xl;
|
||||
padding-bottom: @spacing-xxl;
|
||||
.demand-page {
|
||||
padding-top: @spacing-lg;
|
||||
// 固定底条 72px + 呼吸间距,避免遮住 ③ 卡片
|
||||
padding-bottom: 104px;
|
||||
|
||||
&.is-loading {
|
||||
.demand {
|
||||
opacity: 0.6;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.demand {
|
||||
// 设计稿:页头下与首块间距 ≈ 20px
|
||||
&__head {
|
||||
.flex(column, flex-start);
|
||||
.flex(column, flex-start, stretch);
|
||||
gap: @spacing-xs;
|
||||
margin-bottom: @spacing-base;
|
||||
}
|
||||
|
||||
&__title {
|
||||
@@ -136,16 +148,44 @@ onMounted(() => {
|
||||
|
||||
&__subtitle {
|
||||
font-size: @font-size-base;
|
||||
color: @text-color-secondary;
|
||||
}
|
||||
|
||||
&__nav {
|
||||
.flex(row, space-between);
|
||||
width: 100%;
|
||||
&__card {
|
||||
padding: @spacing-lg;
|
||||
border-radius: @radius-base;
|
||||
background: @white;
|
||||
|
||||
// 设计稿块间距 18px
|
||||
& + & {
|
||||
margin-top: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
&__actions {
|
||||
.flex(row, center);
|
||||
gap: @spacing-base;
|
||||
&__section {
|
||||
.flex(row, flex-start, center);
|
||||
gap: @spacing-sm;
|
||||
margin-bottom: @spacing-base;
|
||||
font-size: @font-size-lg;
|
||||
font-weight: 600;
|
||||
color: @heading-color;
|
||||
}
|
||||
|
||||
/** 区块序号:实心蓝圆 + 白色数字 */
|
||||
&__index {
|
||||
.flex(row, center, center);
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 50%;
|
||||
background: @primary-color;
|
||||
font-size: @font-size-sm;
|
||||
font-weight: 600;
|
||||
color: @white;
|
||||
}
|
||||
|
||||
&__required {
|
||||
margin-left: 2px;
|
||||
color: @danger-color;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user