feat 搭建架构骨架

This commit is contained in:
Ironsp
2026-09-24 09:09:47 +08:00
parent dd9f6b77a4
commit 7a2efa3fea
180 changed files with 18967 additions and 9 deletions

151
src/views/demand/index.vue Normal file
View File

@@ -0,0 +1,151 @@
<script setup lang="ts">
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'
const STEP_TITLES = ['选择业务类型', '填写需求信息', '确认信息并补充备注']
const router = useRouter()
const demandStore = useDemandStore()
const userStore = useUserStore()
const { form, step, loading } = storeToRefs(demandStore)
function onSelectBusiness(type: BusinessType): void {
demandStore.patchForm({ businessType: type })
}
function onUpdateDemand(partial: Partial<Demand>): void {
demandStore.patchForm(partial)
}
function onUpload(file: File): void {
demandStore.addAttachment(file)
}
function onRemoveFile(file: Demand['attachments'][number]): 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()
}
onMounted(() => {
void demandStore.loadDraft()
})
</script>
<template>
<div class="demand">
<header class="demand__head">
<h1 class="demand__title">
需求提报
</h1>
<p class="demand__subtitle text-secondary">
填写您的需求信息,专业顾问将快速与您联系
</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>
<div class="demand__nav">
<AppButton :disabled="step === 1 || loading" @click="goPrev">
上一步
</AppButton>
<AppButton v-if="step < 3" type="primary" :disabled="loading" @click="goNext">
下一步
</AppButton>
</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>
</div>
</template>
<style lang="less" scoped>
.demand {
.flex(column, flex-start);
gap: @spacing-base;
padding-top: @spacing-xl;
padding-bottom: @spacing-xxl;
&__head {
.flex(column, flex-start);
gap: @spacing-xs;
}
&__title {
font-size: @font-size-xxl;
font-weight: 600;
color: @heading-color;
}
&__subtitle {
font-size: @font-size-base;
}
&__nav {
.flex(row, space-between);
width: 100%;
}
&__actions {
.flex(row, center);
gap: @spacing-base;
}
}
</style>