Selaa lähdekoodia

add:新增喂养计算器表单部分

zlong 1 vuosi sitten
vanhempi
commit
fc8900c66e

+ 13 - 0
src/model/pet-manual.ts

@@ -32,3 +32,16 @@ export interface Recommends {
   id: string
   keyword: string
 }
+export interface PetCard {
+  image?: string
+  name: string
+}
+export interface StepInfo {
+  step: number
+  title: string
+}
+export interface FeedFormQuestions {
+  title: string
+  question: PetCard[]
+  formType: number
+}

+ 16 - 0
src/pages.json

@@ -26,10 +26,26 @@
       "path": "pages/feed-plan/components/FeedFlogan",
       "type": "page"
     },
+    {
+      "path": "pages/feed-plan/components/FeedForm",
+      "type": "page"
+    },
+    {
+      "path": "pages/feed-plan/components/FeedQuestionnaire",
+      "type": "page"
+    },
+    {
+      "path": "pages/feed-plan/components/FeedStart",
+      "type": "page"
+    },
     {
       "path": "pages/feed-plan/components/FeedStep",
       "type": "page"
     },
+    {
+      "path": "pages/feed-plan/components/ProgressBar",
+      "type": "page"
+    },
     {
       "path": "pages/pet-manual/components/CardList",
       "type": "page"

+ 6 - 1
src/pages/feed-plan/components/FeedFlogan.vue

@@ -2,11 +2,16 @@
 import feedSlogan from '@/static/image/feed-plan/feed-slogan.png'
 import ToolApi from '@/utils'
 
+const props = withDefaults(defineProps<{
+  bottom: number
+}>(), {
+  bottom: 70,
+})
 const safeBottomMenuHeight = ToolApi.getMenuButtonInfoHeight()
 </script>
 
 <template>
-  <view class="w-screen fixed left-0" :style="{ bottom: `${safeBottomMenuHeight + 70}px` }">
+  <view class="w-screen fixed left-0" :style="{ bottom: `${safeBottomMenuHeight + props.bottom}px` }">
     <image :src="feedSlogan" class="w-[138px] h-[38px] mx-auto" />
   </view>
 </template>

+ 48 - 0
src/pages/feed-plan/components/FeedForm.vue

@@ -0,0 +1,48 @@
+<script setup lang="ts">
+import type { PetCard } from '@/model/pet-manual'
+
+const props = withDefaults(defineProps<{
+  title: string
+  formType: number
+  answerList: PetCard[]
+}>(), {
+  title: '',
+  formType: 1,
+})
+const emits = defineEmits(['next'])
+function handleChooseAnswer(answer: PetCard) {
+  emits('next', answer)
+}
+</script>
+
+<template>
+  <view class="w-full flex justify-center items-center text-[20px] font-bold" :style="{ marginTop: formType === 3 ? '29px' : '69px' }">
+    {{ props.title }}
+  </view>
+  <view v-if="formType === 1" class="flex w-full justify-center items-center mt-[37px] gap-3">
+    <view v-for="(item, index) in props.answerList" :key="index" class="w-[136px] h-[154px] bg-[white] rounded-lg flex flex-col items-center " @click="handleChooseAnswer(item)">
+      <image v-if="index === 0" :src="item?.image" class="w-[76px] h-[69px] mt-[40px]" />
+      <image v-else :src="item?.image" class="w-[96px] h-[73px] mt-[35px]" />
+      <text class="mt-3">
+        {{ item.name }}
+      </text>
+    </view>
+  </view>
+  <view v-if="formType === 2" class="flex flex-col w-full justify-center items-center mt-[37px] gap-4">
+    <view v-for="(item, index) in props.answerList" :key="index" class="w-[200px] h-[56px] bg-[white] rounded-3 flex items-center justify-center" @click="handleChooseAnswer(item)">
+      {{ item.name }}
+    </view>
+  </view>
+  <view v-if="formType === 3" class="flex flex-wrap w-full justify-center items-center mt-[39px] gap-2.5">
+    <view v-for="(item, index) in answerList" :key="index" class="w-[143px] h-[134px] bg-[white] rounded-5 flex flex-col items-center text-[12px]" @click="handleChooseAnswer(item)">
+      <image :src="item.image" class="w-[101px] h-[76px] mt-[21px]" />
+      <text class="mt-[13px]">
+        {{ item.name }}
+      </text>
+    </view>
+  </view>
+</template>
+
+<style scoped>
+
+</style>

+ 52 - 0
src/pages/feed-plan/components/FeedQuestionnaire.vue

@@ -0,0 +1,52 @@
+<script setup lang="ts">
+import type { FeedFormQuestions, PetCard, StepInfo } from '@/model/pet-manual'
+import FeedSlogan from '@/pages/feed-plan/components/FeedFlogan.vue'
+import FeedForm from '@/pages/feed-plan/components/FeedForm.vue'
+import ProgressBar from '@/pages/feed-plan/components/ProgressBar.vue'
+
+const props = defineProps<{
+  list: FeedFormQuestions[]
+  stepInfo: StepInfo[]
+}>()
+const emits = defineEmits(['back', 'step'])
+const step = ref(0)
+const progressNumber = computed<number>(() => {
+  return Math.ceil((step.value + 1) / props.list.length * 100)
+})
+const feedSloganBottom = computed<number>(() => {
+  return props.list[step.value].formType === 3 ? 40 : 70
+})
+const feedProgressTitle = computed<string>(() => {
+  return step.value === 0 ? '返回' : '上一题'
+})
+
+function handlePrevious() {
+  if (step.value > 0) {
+    step.value -= 1
+  }
+  else {
+    emits('back')
+  }
+}
+function handleAnswer(answer: PetCard) {
+  console.log(answer, '答案')
+  if (step.value === 2 || step.value === 7) {
+    emits('step', step.value)
+  }
+  if (step.value < props.list.length - 1) {
+    step.value += 1
+    console.log(step.value, 'step')
+  }
+}
+</script>
+
+<template>
+  <ProgressBar :progress="progressNumber" :title-name="feedProgressTitle" @previous="handlePrevious" />
+  <FeedForm :form-type="props.list[step].formType" :answer-list="props.list[step].question" :title="props.list[step].title" @next="handleAnswer" />
+  <FeedSlogan :bottom="feedSloganBottom" />
+</template>
+
+<style scoped>
+
+</style>
++

+ 34 - 0
src/pages/feed-plan/components/FeedStart.vue

@@ -0,0 +1,34 @@
+<script setup lang="ts">
+import type { StepInfo } from '@/model/pet-manual'
+import FeedFlogan from '@/pages/feed-plan/components/FeedFlogan.vue'
+import FeedStep from '@/pages/feed-plan/components/FeedStep.vue'
+import feedTitle from '@/static/image/feed-plan/feed-title.png'
+
+const props = defineProps<{
+  stepInfo: StepInfo[]
+}>()
+const emits = defineEmits(['ready'])
+function handleReady() {
+  emits('ready')
+}
+</script>
+
+<template>
+  <view class="w-[273px] h-[125px] mx-auto mt-[105px]">
+    <image :src="feedTitle" class="w-full h-full" />
+  </view>
+
+  <view class="h-[121px] ml-15 mt-14">
+    <FeedStep :list="props.stepInfo" />
+  </view>
+  <FeedFlogan />
+  <view class="flex items-center justify-center">
+    <button class="w-[176px] h-[47px] flex items-center justify-center bg-[#4545E5] border-none text-[white] rounded-3xl mt-[87px]" @tap="handleReady">
+      准备好了
+    </button>
+  </view>
+</template>
+
+<style scoped>
+
+</style>

+ 36 - 0
src/pages/feed-plan/components/ProgressBar.vue

@@ -0,0 +1,36 @@
+<script setup lang="ts">
+import back from '@/static/image/pet-parameters/back.png'
+
+const props = withDefaults(defineProps<{
+  titleName: string
+  progress: number
+}>(), {
+  titleName: '返回',
+  progress: 0,
+})
+
+const emits = defineEmits(['previous'])
+
+function handleBack() {
+  emits('previous')
+}
+</script>
+
+<template>
+  <view class="m-4 flex items-center">
+    <image :src="back" class="w-[6px] h-[10px]" @click="handleBack" />
+    <text class="text-[12px] font-pingfangsc ml-1" @click="handleBack">
+      {{ props.titleName }}
+    </text>
+    <view class="flex-1 h-[6px] bg-[#E7E7E7] ml-3 rounded relative">
+      <view class="absolute h-[6px] bg-[#0052D9] rounded" :style="{ width: `${props.progress}%` }" />
+    </view>
+    <text class="text-[12px] font-pingfangsc ml-3">
+      {{ props.progress }}%
+    </text>
+  </view>
+</template>
+
+<style scoped>
+
+</style>

+ 49 - 48
src/pages/feed-plan/index.vue

@@ -1,10 +1,16 @@
 <script setup lang="ts">
-import FeedFlogan from '@/pages/feed-plan/components/FeedFlogan.vue'
+import type { FeedFormQuestions } from '@/model/pet-manual'
+import FeedQuestionnaire from '@/pages/feed-plan/components/FeedQuestionnaire.vue'
+import FeedStart from '@/pages/feed-plan/components/FeedStart.vue'
 import FeedStep from '@/pages/feed-plan/components/FeedStep.vue'
-import feedTitle from '@/static/image/feed-plan/feed-title.png'
-import back from '@/static/image/pet-parameters/back.png'
 import cat from '@/static/image/pet-parameters/cat.png'
 import dog from '@/static/image/pet-parameters/dog.png'
+import emaciatedCat from '@/static/image/pet-parameters/form/emaciated_cat.png'
+import idealWightCat from '@/static/image/pet-parameters/form/idealweight_cat.png'
+import overWeightCat from '@/static/image/pet-parameters/form/overweight_cat.png'
+import skinnyCat from '@/static/image/pet-parameters/form/skinny_cat.png'
+import thinCat from '@/static/image/pet-parameters/form/thin_cat.png'
+import underWeightCat from '@/static/image/pet-parameters/form/underweight_cat.png'
 import ToolApi from '@/utils'
 
 interface StepInfo {
@@ -13,31 +19,59 @@ interface StepInfo {
 }
 const titleName = ref<string>('喂养计算器')
 const safeHeight = ToolApi.getSafeHeight()
+const stage = ref<number>(0)
 const stepInfo = ref<StepInfo[]>([
   { step: 1, title: '宠物基础信息' },
   { step: 2, title: '身体状态信息' },
   { step: 3, title: '计算喂养计划' },
 ])
 const controlFormDisplay = ref({
-  display1: false,
+  display1: true,
   display2: false,
-  display3: true,
+  display3: false,
 })
-const animalCard = ref([
-  { image: cat, name: '猫猫' },
-  { image: dog, name: '狗狗' },
+const feedFormQuestions = ref<FeedFormQuestions[]>([
+  { title: '您的动物是?', question: [{ image: cat, name: '猫猫' }, { image: dog, name: '狗狗' }], formType: 1 },
+  { title: '猫咪的性别?', question: [{ name: '男孩' }, { name: '女孩' }], formType: 2 },
+  { title: '猫咪的年龄区间?', question: [{ name: '0-4个月' }, { name: '5-12个月' }], formType: 2 },
+  { title: '猫咪是否活跃?', question: [{ name: '活跃' }, { name: '不活跃' }], formType: 2 },
+  { title: '猫咪是否怀孕?', question: [{ name: '怀孕' }, { name: '未怀孕' }], formType: 2 },
+  { title: '猫咪是否绝育?', question: [{ name: '绝育' }, { name: '未绝育' }], formType: 2 },
+  { title: '猫咪是否在哺乳?', question: [{ name: '哺乳中' }, { name: '未哺乳' }], formType: 2 },
+  { title: '请选择猫咪的体型', question: [{ image: emaciatedCat, name: '极度消廋' }, { image: skinnyCat, name: '非常廋' }, { image: thinCat, name: '消瘦' }, { image: underWeightCat, name: '体重偏低' }, { image: idealWightCat, name: '理想体重' }, { image: overWeightCat, name: '体重偏重' }], formType: 3 },
 ])
-function handleReady() {
+function reset() {
+  stage.value = 0
   controlFormDisplay.value = {
     display1: false,
     display2: false,
     display3: false,
   }
+}
+function handleReady() {
+  reset()
   controlFormDisplay.value.display2 = true
   setTimeout(() => {
-    controlFormDisplay.value.display2 = false
+    reset()
     controlFormDisplay.value.display3 = true
-  }, 2000)
+  }, 3000)
+}
+function handleBackFeedStart() {
+  reset()
+  controlFormDisplay.value.display1 = true
+}
+function handleStep(step: number) {
+  if (step === 2) {
+    handleReady()
+    stage.value = 1
+    controlFormDisplay.value.display2 = true
+  }
+  else if (step === 7) {
+    reset()
+    stage.value = 2
+    controlFormDisplay.value.display2 = true
+    controlFormDisplay.value.display3 = false
+  }
 }
 </script>
 
@@ -45,46 +79,13 @@ function handleReady() {
   <TitleBar :title-name="titleName" />
   <view class="flex flex-col bg-[#F5F6F7] overflow-y-auto" :style="`height:calc(100vh - ${safeHeight}px)`">
     <view v-show="controlFormDisplay.display1">
-      <view class="w-[273px] h-[125px] mx-auto mt-[105px]">
-        <image :src="feedTitle" class="w-full h-full" />
-      </view>
-
-      <view class="h-[121px] ml-15 mt-14">
-        <FeedStep :list="stepInfo" />
-      </view>
-      <FeedFlogan />
-      <view class="flex items-center justify-center">
-        <button class="w-[176px] h-[47px] flex items-center justify-center bg-[#4545E5] border-none text-[white] rounded-3xl mt-[87px]" @tap="handleReady">
-          准备好了
-        </button>
-      </view>
+      <FeedStart :step-info="stepInfo" @ready="handleReady" />
     </view>
-    <view v-show="controlFormDisplay.display2" class="flex items-center justify-center w-full h-full">
-      <FeedStep :list="stepInfo" :stage="stepInfo[0].step - 1" />
+    <view v-show="controlFormDisplay.display2" class="flex justify-center items-center w-full h-full">
+      <FeedStep :list="stepInfo" :stage="stage" />
     </view>
     <view v-show="controlFormDisplay.display3">
-      <view class="m-4 flex items-center">
-        <image :src="back" class="w-[6px] h-[10px]" />
-        <text class="text-[12px] font-pingfangsc ml-1">
-          返回
-        </text>
-        <view class="flex-1 h-[6px] bg-[#E7E7E7] ml-3 rounded relative">
-          <view class="absolute h-[6px] bg-[#0052D9] rounded" style="width: 80%" />
-        </view>
-        <text class="text-[12px] font-pingfangsc ml-3">
-          80%
-        </text>
-      </view>
-      <view class="mt-[69px] w-full flex justify-center items-center text-[20px] font-bold">
-        您的宠物是?
-      </view>
-      <view class="flex w-full justify-center items-center mt-[37px] gap-3">
-        <view v-for="(item, index) in animalCard" :key="index" class="w-[136px] h-[154px] bg-[white] rounded-lg flex justify-center">
-          <image v-if="index === 0" :src="animalCard[0].image" class="w-[76px] h-[69px] mt-[40px]" />
-          <image v-else :src="animalCard[1].image" class="w-[96px] h-[73px] mt-[35px]" />
-        </view>
-      </view>
-      <FeedFlogan />
+      <FeedQuestionnaire :list="feedFormQuestions" :step-info="stepInfo" @back="handleBackFeedStart" @step="handleStep" />
     </view>
   </view>
 </template>

BIN
src/static/image/pet-parameters/form/emaciated_cat.png


BIN
src/static/image/pet-parameters/form/idealweight_cat.png


BIN
src/static/image/pet-parameters/form/overweight_cat.png


BIN
src/static/image/pet-parameters/form/skinny_cat.png


BIN
src/static/image/pet-parameters/form/thin_cat.png


BIN
src/static/image/pet-parameters/form/underweight_cat.png


+ 4 - 0
src/uni-pages.d.ts

@@ -9,7 +9,11 @@ interface NavigateToOptions {
        "/pages/me/index" |
        "/pages/pet-manual/index" |
        "/pages/feed-plan/components/FeedFlogan" |
+       "/pages/feed-plan/components/FeedForm" |
+       "/pages/feed-plan/components/FeedQuestionnaire" |
+       "/pages/feed-plan/components/FeedStart" |
        "/pages/feed-plan/components/FeedStep" |
+       "/pages/feed-plan/components/ProgressBar" |
        "/pages/pet-manual/components/CardList";
 }
 interface RedirectToOptions extends NavigateToOptions {}