Forráskód Böngészése

voluntary result - tmp save

abpcoder 2 hete
szülő
commit
c4cb4737b8

+ 24 - 0
src/pagesOther/pages/voluntary/result/components/plus/voluntary-result-card.vue

@@ -0,0 +1,24 @@
+<template>
+    <view class="p-25 flex justify-between items-start gap-20 rounded-xl border border-solid border-sky-300"
+          style="background: linear-gradient(to bottom, #EAF8FF 0%, #FFFFFF 36.82%)">
+        <slot name="title">
+            <voluntary-result-tag :tag="tag"/>
+        </slot>
+        <slot/>
+    </view>
+</template>
+
+<script setup lang="ts">
+import VoluntaryResultTag from "@/pagesOther/pages/voluntary/result/components/plus/voluntary-result-tag.vue";
+
+defineProps({
+    tag: {
+        type: String,
+        default: ''
+    }
+})
+</script>
+
+<style scoped>
+
+</style>

+ 32 - 0
src/pagesOther/pages/voluntary/result/components/plus/voluntary-result-progress.vue

@@ -0,0 +1,32 @@
+<template>
+    <view class="w-full flex justify-between items-center gap-20">
+        <view class="text-28 text-fore-title shrink-0" :style="{width: labelWidth}">{{ label }}</view>
+        <div class="w-full h-24 rounded-full bg-gray-200 overflow-hidden">
+            <div class="h-full rounded-full bg-blue-300" :style="{width: progress+'%'}" />
+        </div>
+        <view class="text-30 text-fore-title text-right shrink-0" :style="{width: scoreWidth}">
+            <text>{{ score }}</text>
+            <text class="text-24 text-fore-placeholder">/{{ total }}</text>
+        </view>
+    </view>
+</template>
+
+<script setup lang="ts" name="VoluntaryResultProgress">
+
+// import {VoluntaryScoreItem} from "@/types/voluntary";
+
+// const props = defineProps<VoluntaryScoreItem>()
+const props = defineProps({
+    label: String,
+    score: Number,
+    total: Number,
+    labelWidth: String,
+    scoreWidth: String
+})
+
+const progress = computed(() => props.total && props.score ? props.score * 100 / props.total : 0)
+</script>
+
+<style scoped>
+
+</style>

+ 19 - 0
src/pagesOther/pages/voluntary/result/components/plus/voluntary-result-tag.vue

@@ -0,0 +1,19 @@
+<template>
+    <view class="px-7 py-3 text-nowrap text-23 text-white rounded"
+          style="background: linear-gradient(to right, #16AFF5 0%, #91E0FE 100%)">
+        {{ tag }}
+    </view>
+</template>
+
+<script setup lang="ts">
+defineProps({
+    tag: {
+        type: String,
+        default: ''
+    }
+})
+</script>
+
+<style scoped>
+
+</style>

+ 0 - 0
src/pagesOther/pages/voluntary/result/components/voluntary-result-title.vue → src/pagesOther/pages/voluntary/result/components/plus/voluntary-result-title.vue


+ 110 - 66
src/pagesOther/pages/voluntary/result/components/voluntary-result-analysis.vue

@@ -1,17 +1,64 @@
 <template>
     <view class="p-28 bg-white rounded-xl">
         <voluntary-result-title title="概率分析"/>
-        <view class="h-100">
+        <view class="h-220">
             <ie-echart :option="option"/>
         </view>
+        <voluntary-result-card tag="评估">
+            <view class="flex-1 text-23 leading-38 text-fore-title">
+                根据历年数据对比分析,预估目前成绩报考该院校/专业,录取风险属于
+                <text class="text-danger">较高风险</text>
+            </view>
+        </voluntary-result-card>
     </view>
 </template>
 
 <script setup lang="ts" name="VoluntaryResultAnalysis">
-import VoluntaryResultTitle from "@/pagesOther/pages/voluntary/result/components/voluntary-result-title.vue";
+import VoluntaryResultTitle from "@/pagesOther/pages/voluntary/result/components/plus/voluntary-result-title.vue";
+import IeEchart from "@/pagesOther/components/ie-echart/ie-echart.vue";
+import VoluntaryResultCard from "@/pagesOther/pages/voluntary/result/components/plus/voluntary-result-card.vue";
 
 const option = ref({})
 const drawRing = (rate: number | null) => {
+    const baseGauge = {
+        type: 'gauge',
+        center: ['50%', '75%'],
+        startAngle: 180,
+        endAngle: 0,
+        min: 0,
+        max: 100,
+        radius: '150%',
+        itemStyle: {
+            show: false,
+        },
+        progress: {
+            show: false,
+        },
+        pointer: {
+            show: false,
+        },
+        anchor: {
+            show: false
+        },
+        axisLine: {
+            show: false
+        },
+        axisTick: {
+            show: false
+        },
+        splitLine: {
+            show: false
+        },
+        axisLabel: {
+            show: false,
+        },
+        detail: {
+            show: false,
+        },
+        title: {
+            show: false
+        }
+    }
     option.value = {
         grid: {
             left: 0,
@@ -19,13 +66,30 @@ const drawRing = (rate: number | null) => {
         },
         series: [
             {
-                type: 'gauge',
-                center: ['50%', '75%'],
-                startAngle: 180,
-                endAngle: 0,
-                min: 0,
-                max: 100,
-                radius: '120%',
+                ...baseGauge,
+                radius: '145%',
+                axisLine: {
+                    roundCap: true,
+                    lineStyle: {
+                        color: [[1, '#e2e2e2']],
+                        width: 10
+                    }
+                }
+            },
+            {
+                ...baseGauge,
+                radius: '115%',
+                axisLine: {
+                    roundCap: true,
+                    lineStyle: {
+                        color: [[1, '#F8F8F8']],
+                        width: 2
+                    }
+                }
+            },
+            {
+                ...baseGauge,
+                radius: '150%',
                 itemStyle: {
                     color: {
                         type: 'linear',
@@ -43,45 +107,24 @@ const drawRing = (rate: number | null) => {
                 progress: {
                     show: true,
                     roundCap: true,
-                    width: 10,
-                },
-                pointer: {
-                    show: false,
-                },
-                anchor: {
-                    show: false
-                },
-                axisLine: {
-                    roundCap: true,
-                    lineStyle: {
-                        color: [[1, '#e2e2e2']],
-                        width: 10
-                    }
-                },
-                axisTick: {
-                    show: false
-                },
-                splitLine: {
-                    show: false
-                },
-                axisLabel: {
-                    show: false,
+                    width: 16
                 },
                 detail: {
                     show: true,
                     formatter: (v: any) => {
                         return isNaN(v) ? '--' : (v + '%');
                     },
-                    color: '#333',
+                    color: '#1A1A1A',
+                    fontFamily: 'KaTeX_SansSerif',
+                    fontWeight: '700',
                     fontSize: 20,
-                    fontWeight: 'bold',
-                    offsetCenter: [0, '-20%']
+                    offsetCenter: [0, '-28%']
                 },
                 title: {
                     show: true,
                     color: '#666666',
-                    fontSize: 10,
-                    offsetCenter: [0, '20%'],
+                    fontSize: 12,
+                    offsetCenter: [0, 0],
                 },
                 data: [
                     {
@@ -91,29 +134,18 @@ const drawRing = (rate: number | null) => {
                 ]
             },
             {
-                type: 'gauge',
-                center: ['50%', '75%'],
-                startAngle: 180,
-                endAngle: 0,
-                min: 0,
-                max: 100,
-                radius: '120%',
+                ...baseGauge,
+                radius: '150%',
                 z: 3,
-                progress: {
-                    show: false,
-                },
                 pointer: {
                     showAbove: true,
                     icon: 'circle',
-                    width: 7,
-                    offsetCenter: [0, '-61%'],
+                    width: 14,
+                    offsetCenter: [0, '-60.5%'],
                     itemStyle: {
                         color: '#fff'
                     }
                 },
-                anchor: {
-                    show: false
-                },
                 axisLine: {
                     roundCap: true,
                     lineStyle: {
@@ -121,20 +153,31 @@ const drawRing = (rate: number | null) => {
                         width: 10
                     }
                 },
-                axisTick: {
-                    show: false
-                },
-                splitLine: {
-                    show: false
-                },
-                axisLabel: {
-                    show: false,
-                },
-                detail: {
-                    show: false,
+                data: [
+                    {
+                        value: rate
+                    }
+                ]
+            },
+            {
+                ...baseGauge,
+                radius: '150%',
+                z: 3,
+                pointer: {
+                    showAbove: true,
+                    icon: 'circle',
+                    width: 8,
+                    offsetCenter: [0, '-60.5%'],
+                    itemStyle: {
+                        color: '#31A0FC'
+                    }
                 },
-                title: {
-                    show: false,
+                axisLine: {
+                    roundCap: true,
+                    lineStyle: {
+                        color: [[1, 'transparent']],
+                        width: 10
+                    }
                 },
                 data: [
                     {
@@ -146,9 +189,10 @@ const drawRing = (rate: number | null) => {
     }
 }
 
+
 onMounted(async () => {
     await nextTick()
-    drawRing(70)
+    drawRing(81)
 })
 </script>
 

+ 10 - 0
src/pagesOther/pages/voluntary/result/components/voluntary-result-history.vue

@@ -0,0 +1,10 @@
+<template>
+
+</template>
+
+<script setup lang="ts" name="VoluntaryResultHistory">
+</script>
+
+<style scoped>
+
+</style>

+ 59 - 0
src/pagesOther/pages/voluntary/result/components/voluntary-result-score.vue

@@ -0,0 +1,59 @@
+<template>
+    <view class="p-28 bg-white rounded-xl">
+        <voluntary-result-title title="学生分数"/>
+        <view class="p-28 gap-28 flex flex-col">
+            <voluntary-result-progress v-for="i in progressList" :key="i.label" v-bind="i"/>
+        </view>
+        <voluntary-result-card tag="分析">
+            <view class="flex-1 text-23 leading-38 text-fore-title">
+                该专业考试总分为<text class="text-primary">600</text>分,您当前成绩为<text class="text-primary">340</text>分。
+                参考<text>2025</text>年录取分数线,预估还需再提升<text class="text-primary">11</text>分即可达标!
+            </view>
+        </voluntary-result-card>
+    </view>
+</template>
+
+<script setup lang="ts" name="VoluntaryResultScore">
+import VoluntaryResultTitle from "@/pagesOther/pages/voluntary/result/components/plus/voluntary-result-title.vue";
+import VoluntaryResultProgress from "@/pagesOther/pages/voluntary/result/components/plus/voluntary-result-progress.vue";
+import VoluntaryResultCard from "@/pagesOther/pages/voluntary/result/components/plus/voluntary-result-card.vue";
+import {VOLUNTARY_FORM, VOLUNTARY_MODEL} from "@/types/injectionSymbols";
+import {VoluntaryScoreItem} from "@/types/voluntary";
+import _ from "lodash";
+
+const model = inject(VOLUNTARY_MODEL)
+const data = inject(VOLUNTARY_FORM)
+
+const progressList = computed(() => {
+    const scores = model?.value
+    const form = data?.value
+    if (!scores || !form) return []
+    const results: VoluntaryScoreItem[] = []
+
+    form.rules.forEach(i => {
+        i.details.forEach(r => {
+            results.push({
+                label: r.label,
+                score: Number(scores[r.fieldName]),
+                total: Number(scores[r.fieldName + 'Total']),
+                labelWidth: '',
+                scoreWidth: ''
+            })
+        })
+    })
+    // 因为label score需要全局对齐,所以拼装的逻辑在progress外层
+    const maxLabel = _.chain(results).map(i => i.label.length).max().value()
+    const maxScore = _.chain(results).map(i => (i.score + '/' + i.total).length).max().value()
+    const labelWidth = maxLabel * 29
+    const scoreWidth = maxScore * 18
+    results.forEach(i => {
+        i.labelWidth = labelWidth + 'rpx'
+        i.scoreWidth = scoreWidth + 'rpx'
+    })
+    return results
+})
+</script>
+
+<style scoped>
+
+</style>

+ 4 - 2
src/pagesOther/pages/voluntary/result/result.vue

@@ -5,9 +5,10 @@
         <view class="h-90" style="background: linear-gradient(to Right, rgba(100, 200, 255, 1), rgba(165, 229, 255, 0.87))"/>
         <!-- #endif -->
         <ie-image is-oss src="/volunteer/voluntary/result/banner.png"/>
-        <view class="px-30 flex flex-col gap-30 -mt-180 z-1">
+        <view class="px-30 flex flex-col gap-20 -mt-180 z-1">
             <voluntary-form-major class="!bg-white !mt-0"/>
             <voluntary-result-analysis />
+            <voluntary-result-score />
         </view>
         <ie-safe-toolbar :height="84" :shadow="false">
             <view class="px-30 py-16">
@@ -21,9 +22,10 @@
 
 import {useTransferPage} from "@/hooks/useTransferPage";
 import {VoluntaryDto} from "@/types/voluntary";
+import {VOLUNTARY_FORM, VOLUNTARY_MODEL} from "@/types/injectionSymbols";
 import VoluntaryFormMajor from "@/pagesOther/pages/voluntary/index/components/voluntary-form-major.vue";
 import VoluntaryResultAnalysis from "@/pagesOther/pages/voluntary/result/components/voluntary-result-analysis.vue";
-import {VOLUNTARY_FORM, VOLUNTARY_MODEL} from "@/types/injectionSymbols";
+import VoluntaryResultScore from "@/pagesOther/pages/voluntary/result/components/voluntary-result-score.vue";
 
 const {prevData} = useTransferPage<VoluntaryDto, any>()
 const data = computed(() => prevData.value.data)

+ 8 - 0
src/types/voluntary.ts

@@ -44,4 +44,12 @@ export interface VoluntaryModel extends Record<string, string | number | null> {
 export interface VoluntaryDto {
     data: SelectedCollegeMajorWithRules;
     model: VoluntaryModel;
+}
+
+export interface VoluntaryScoreItem {
+    label: string;
+    score: number;
+    total: number;
+    labelWidth?: string;
+    scoreWidth?: string;
 }