abpcoder 5 дней назад
Родитель
Сommit
f9de8843d5

+ 2 - 1
src/api/modules/university.ts

@@ -9,7 +9,8 @@ export function universityList(params: Record<string, any>) {
 
 // 院校库 - 院校梯队
 export function universityListByTier() {
-  return flyio.get('/front/university/listByTier') as Promise<ApiResponseList<UniversityTier>>
+  // 返回全量,不需要分页
+  return flyio.get('/front/university/listByTier') as Promise<ApiResponse<UniversityTier[]>>
 }
 
 /**

+ 21 - 10
src/api/modules/voluntary.ts

@@ -3,33 +3,44 @@ import flyio from "../flyio";
 import {SelectedUniversityMajor} from "@/types/study";
 import {EnrollRule, VoluntaryRecord, VoluntaryResult} from "@/types/voluntary";
 
-export function getRenderRules(params: SelectedUniversityMajor) {
+export function getRenderRules(um: SelectedUniversityMajor) {
     // 普通高中,EnrollRuleItem.readonly=true 取学考成绩
-    return flyio.post('/voluntary/getRenderRules', params) as Promise<ApiResponseList<EnrollRule>>
+    const {universityId, majorId} = um
+    return flyio.post('/voluntary/getRenderRules', {universityId, majorId}) as Promise<ApiResponse<EnrollRule[]>>
 }
 
 export function getSkillRules(params: SelectedUniversityMajor) {
     // EnrollRule 需要返回文化+职业,但职业EnrollRule.details = []不需要返回字段规则
-    return flyio.post('/voluntary/getSkillRules', params) as Promise<ApiResponseList<EnrollRule>>
+    const {universityId, majorId} = um
+    return flyio.post('/voluntary/getSkillRules', {universityId, majorId}) as Promise<ApiResponse<EnrollRule[]>>
 }
 
-export function postRenderRules(target: SelectedCollegeMajor, model: Record<string, any>) {
-    return flyio.post('/voluntary/postRenderRules', {target, model}) as Promise<ApiResponse<VoluntaryResult>>
+export function postRenderRules(target: SelectedUniversityMajor, model: Record<string, any>) {
+    const {universityId, majorId} = target
+    return flyio.post('/voluntary/postRenderRules', {
+        target: {universityId, majorId},
+        model
+    }) as Promise<ApiResponse<VoluntaryResult>>
 }
 
 export function postSkillRules(target: SelectedUniversityMajor, model: Record<string, any>) {
     // VoluntaryResult.histories 不需要返回
-    return flyio.post('/voluntary/postSkillRules', {target, model}) as Promise<ApiResponse<VoluntaryResult>>
+    const {universityId, majorId} = target
+    return flyio.post('/voluntary/postSkillRules', {
+        target: {universityId, majorId},
+        model
+    }) as Promise<ApiResponse<VoluntaryResult>>
 }
 
-export function getVoluntaryList(params) {
+export function getVoluntaryList() {
     // 此接口不分页,全部返回
-    return flyio.get('/voluntary/getVoluntaryList') as Promise<ApiResponseList<VoluntaryRecord>>
+    return flyio.get('/voluntary/getVoluntaryList') as Promise<ApiResponse<VoluntaryRecord[]>>
 }
 
-export function addVoluntary(data: SelectedUniversityMajor) {
+export function addVoluntary(data: Partial<SelectedUniversityMajor>) {
     // 注意合并,数量限制(1个院校6个?确认一下),
-    return flyio.post('/voluntary/addVoluntary', data)
+    const {universityId, majorId} = data
+    return flyio.post('/voluntary/addVoluntary', {universityId, majorId})
 }
 
 export function removeVoluntaryByUniversity(universityId) {

+ 4 - 0
src/common/routes.ts

@@ -31,6 +31,10 @@ export const routes = {
   * 院校选择
   * */
   universityPicker: '/pagesOther/pages/university/picker/picker',
+  /*
+  * 院校专业选择
+  * */
+  targetPicker: '/pagesStudy/pages/targeted-add/targeted-add',
   /**
    * 职业库
    */

+ 1 - 1
src/pagesMain/pages/volunteer/components/volunteer-tier.vue

@@ -50,7 +50,7 @@ const goCollegeDetail = (u: University) => {
 
 onMounted(async () => {
     const res = await universityListByTier()
-    list.value = res.rows.map((item, idx) => {
+    list.value = res.data.map((item, idx) => {
         const conf = uiConfig[idx % uiConfig.length]
         return {
             ...item,

+ 5 - 4
src/pagesOther/pages/university/index/components/college-list.vue

@@ -21,6 +21,7 @@ import {University, UniversityQueryDto} from "@/types/university";
 import {UNIVERSITY_FILTER} from "@/types/injectionSymbols";
 import CollegeConditionsPicker from "@/pagesOther/pages/university/index/components/plus/college-conditions-picker.vue";
 import CollegeItem from "@/pagesOther/pages/university/index/components/plus/college-item.vue";
+import {routes} from "@/common/routes";
 
 const props = withDefaults(defineProps<{
     customItemClick: boolean;
@@ -56,10 +57,10 @@ const handleQuery = (pageNum: number, pageSize: number) => {
         .catch(e => paging.value?.complete(false))
 }
 
-const handleDetail = (college: University) => {
-    if (props.customItemClick) return emits('item-click', college)
-    const {code} = college
-    transferTo('/pages/college-library/detail/detail', {code})
+const handleDetail = (u: University) => {
+    if (props.customItemClick) return emits('item-click', u)
+    const {id, code} = u
+    transferTo(routes.universityDetail, {data: {id, code}})
 }
 
 provide(UNIVERSITY_FILTER, queryParams)

+ 2 - 2
src/pagesOther/pages/university/picker/picker.vue

@@ -17,8 +17,8 @@ import {University} from "@/types/university";
 const {prevData, transferBack} = useTransferPage<Transfer.UniversityPickerPageOptions, {}>()
 const title = computed(() => prevData.value.title || '选择院校')
 
-const handleItemClick = (college: University) => {
-    transferBack(college)
+const handleItemClick = (u: University) => {
+    transferBack(u)
 }
 </script>
 

+ 10 - 11
src/pagesOther/pages/voluntary/index/components/voluntary-form-core.vue

@@ -1,6 +1,6 @@
 <template>
     <view v-if="rulesInit" class="mt-40 flex flex-col gap-30">
-        <view v-for="(r,i) in data.rules.filter(i => i.details?.length)" :key="i" class="flex flex-col gap-30">
+        <view v-for="(r,i) in renderRules.filter(i => i.details?.length)" :key="i" class="flex flex-col gap-30">
             <view class="text-32 font-bold">{{ r.category }}</view>
             <uv-form ref="form" :model="model" :rules="rules" label-position="top">
                 <uv-form-item v-for="d in r.details" :key="d.fieldName" :prop="d.fieldName">
@@ -17,15 +17,14 @@
     </view>
 </template>
 
-<script setup lang="ts" name="VoluntaryFormCore">
-import {VOLUNTARY_FORM, VOLUNTARY_MODEL} from "@/types/injectionSymbols";
-import {EnrollRule, EnrollRuleItem, SelectedCollegeMajorWithRules, VoluntaryModel} from "@/types/voluntary";
-import {Ref} from "@vue/runtime-core";
+<script setup lang="ts">
+import {VOLUNTARY_RULES, VOLUNTARY_MODEL} from "@/types/injectionSymbols";
+import {EnrollRule, EnrollRuleItem, VoluntaryModel} from "@/types/voluntary";
 import _ from "lodash";
 
-const data = inject(VOLUNTARY_FORM) as Ref<SelectedCollegeMajorWithRules>
-const model = inject(VOLUNTARY_MODEL) as Ref<VoluntaryModel>
-const form = ref<{ validate: () => Promise<void> }[] | null>(null)
+const renderRules = inject(VOLUNTARY_RULES) || ref<EnrollRule[]>()
+const model = inject(VOLUNTARY_MODEL) || ref<VoluntaryModel>({})
+const form = ref<{ validate: () => Promise<void> }[]>()
 const rules = ref({})
 const rulesInit = ref(false)
 
@@ -40,10 +39,10 @@ const validate = () => {
     return Promise.all(validates)
 }
 
-watch([data, model], ([data, model]) => {
-    if (!data || !model) return
+watch([renderRules, model], ([renderRules, model]) => {
+    if (!renderRules || !model) return
     const autoRules: Record<string, any> = {}
-    data.rules.forEach((item: EnrollRule) => {
+    renderRules.forEach((item: EnrollRule) => {
         item.details.forEach((r: EnrollRuleItem) => {
             // TODO: 此规则逻辑从旧的uni-vueuse mx-base分支迁移过来,可能不完全适用于新版本。
             const fieldRules = []

+ 8 - 8
src/pagesOther/pages/voluntary/index/components/voluntary-form-major.vue

@@ -1,28 +1,28 @@
 <template>
     <view class="mt-24 p-28 flex items-center gap-24 bg-back-light rounded-10" :class="props.customClass">
-        <ie-image :src="data.universityLogo" custom-class="w-80 h-80"/>
+        <ie-image :src="target.universityLogo" custom-class="w-80 h-80"/>
         <view class="flex-1">
-            <view class="text-28 text-fore-title font-bold">{{ data.universityName }}</view>
+            <view class="text-28 text-fore-title font-bold">{{ target.universityName }}</view>
             <view class="flex items-center gap-8">
                 <view class="mt-8 w-fit text-20 text-primary border border-solid border-primary rounded-4 px-10 py-4">
-                    {{ data.majorName }}
+                    {{ target.majorName }}
                 </view>
                 <view class="mt-8 w-fit text-20 text-info border border-solid border-info rounded-4 px-10 py-4">
-                    {{ data.majorGroup }}
+                    {{ target.majorGroup }}
                 </view>
             </view>
         </view>
     </view>
 </template>
 
-<script setup lang="ts" name="VoluntaryFormMajor">
-import {VOLUNTARY_FORM} from "@/types/injectionSymbols";
-import {SelectedCollegeMajorWithRules} from "@/types/voluntary";
+<script setup lang="ts">
+import {VOLUNTARY_TARGET} from "@/types/injectionSymbols";
+import {SelectedUniversityMajor} from "@/types/voluntary";
 
 const props = defineProps<{
     customClass?: string;
 }>();
-const data = inject(VOLUNTARY_FORM) || ref({} as SelectedCollegeMajorWithRules)
+const target = inject(VOLUNTARY_TARGET) || ref({} as SelectedUniversityMajor)
 </script>
 
 <style scoped>

+ 6 - 6
src/pagesOther/pages/voluntary/index/components/voluntary-form-rule.vue

@@ -32,18 +32,18 @@
             <text class="ml-12 text-28 text-fore-title font-bold">计分规则说明</text>
         </view>
         <view class="mt-18 text-23 text-fore-title leading-38">
-            <view>考试由{{data.rules.map(r=>r.category).join('+')}}{{data.rules.length}}部分组成。其中:</view>
-            <view v-for="(c,i) in data.rules" :key="i">{{c.category}}={{c.content}}</view>
+            <view>考试由{{rules.map(r=>r.category).join('+')}}{{rules.length}}部分组成。其中:</view>
+            <view v-for="(c,i) in rules" :key="i">{{c.category}}={{c.content}}</view>
         </view>
     </view>
 
 </template>
 
-<script setup lang="ts" name="VoluntaryFormRule">
-import {VOLUNTARY_FORM} from "@/types/injectionSymbols";
-import {SelectedCollegeMajorWithRules} from "@/types/voluntary";
+<script setup lang="ts">
+import {VOLUNTARY_RULES} from "@/types/injectionSymbols";
+import {EnrollRule} from "@/types/voluntary";
 
-const data = inject(VOLUNTARY_FORM) || {} as SelectedCollegeMajorWithRules
+const rules = inject(VOLUNTARY_RULES) || ref<EnrollRule[]>([])
 </script>
 
 <style scoped>

+ 1 - 1
src/pagesOther/pages/voluntary/index/components/voluntary-form-simulate.vue

@@ -8,7 +8,7 @@
     </view>
 </template>
 
-<script lang="ts" setup name="VoluntaryFormSimulate">
+<script lang="ts" setup>
 </script>
 
 <style scoped>

+ 1 - 1
src/pagesOther/pages/voluntary/index/components/voluntary-form.vue

@@ -16,7 +16,7 @@ defineProps({
     disableSimulate: Boolean
 })
 
-const form = ref<InstanceType<typeof VoluntaryFormCore> | null>(null)
+const form = ref<InstanceType<typeof VoluntaryFormCore>>()
 const validate = () => {
     return form.value?.validate()
 }

+ 48 - 130
src/pagesOther/pages/voluntary/index/index.vue

@@ -9,11 +9,11 @@
             <view class="flex justify-between items-center">
                 <view class="text-lg text-fore-title">报考院校专业</view>
                 <view class="text-base text-fore-placeholder flex items-center" @click="handleSelect">
-                    <text>更多</text>
+                    <text>请选择</text>
                     <uv-icon name="arrow-right" color="info"/>
                 </view>
             </view>
-            <ie-empty v-if="!data.rules?.length" :image="emptyImg" text="请选择你的报考院校专业~"/>
+            <ie-empty v-if="!rules.length" :image="emptyImg" text="请选择你的报考院校专业~"/>
             <voluntary-form v-else ref="form"/>
         </view>
         <ie-safe-toolbar :height="84" :shadow="false">
@@ -28,154 +28,72 @@
 
 import config from "@/config";
 import VoluntaryForm from "@/pagesOther/pages/voluntary/index/components/voluntary-form.vue";
-import {SelectedCollegeMajorWithRules, VoluntaryDto, VoluntaryModel, VoluntaryResult} from "@/types/voluntary";
-import {VOLUNTARY_FORM, VOLUNTARY_MODEL} from "@/types/injectionSymbols";
+import {SelectedUniversityMajor} from "@/types/study";
+import {EnrollRule, VoluntaryDto, VoluntaryModel, VoluntaryResult} from "@/types/voluntary";
+import {VOLUNTARY_MODEL, VOLUNTARY_RULES, VOLUNTARY_TARGET} from "@/types/injectionSymbols";
 import {useTransferPage} from "@/hooks/useTransferPage";
 import {routes} from "@/common/routes";
+import {UniversityPickerPageOptions} from "@/types/transfer";
+import {getRenderRules, postRenderRules} from "@/api/modules/voluntary";
 
 const emptyImg = computed(() => config.ossUrl + '/volunteer/voluntary/index/empty_data.png')
 
-const form = ref<InstanceType<typeof VoluntaryForm> | null>(null)
-const data = ref<SelectedCollegeMajorWithRules>({} as SelectedCollegeMajorWithRules)
+const form = ref<InstanceType<typeof VoluntaryForm>>()
+const target = ref<SelectedUniversityMajor>()
+const rules = ref<EnrollRule[]>([])
 const model = ref<VoluntaryModel>({})
 const {transferTo} = useTransferPage<any, VoluntaryDto>()
 
 const handleSelect = async () => {
-    transferTo()
+    const option: UniversityPickerPageOptions = {
+        title: '选择你的报考院校专业',
+        fromVoluntary: true,
+        selectedUniversityId: target.value?.universityId,
+        selectedMajorId: target.value?.majorId
+    }
+    const picked = await transferTo(routes.targetPicker, {data: option})
+    if (!picked) return
+    target.value = picked
+    uni.$ie.showLoading()
+    try {
+        // reset
+        model.value = {}
+        rules.value = []
+        // request render rules
+        const res = await getRenderRules(target.value)
+        rules.value = res.data
+        // init model
+        rules.value.forEach((r) => {
+            r.details.forEach((d) => {
+                if (d.options?.length) {
+                    model.value[d.fieldName] = d.defaultValue ? d.defaultValue : ''
+                    model.value[d.fieldName + 'Total'] = d.options ? d.options[0] : null
+                }
+            })
+        })
+    } catch (e) {
+        console.log('getRenderRules ex', e, target.value)
+        target.value = null // clear for re-pick
+    } finally {
+        uni.$ie.hideLoading()
+    }
 }
 
 const handleSubmit = async () => {
     await form.value?.validate()
     // make request
-    await nextTick()
-    const result: VoluntaryResult = {
-        "universityCode": "12302",
-        "majorCode": "690390",
-        "majorEnrollCode": "68508",
-        "majorGroup": "专业B组",
-        "majorName": "集成电路技术",
-        "majorDirection": "",
-        "enumPickType": "Danger",
-        "enrollRate": 53,
-        "enrollRateText": "风险极高",
-        "tips": null,
-        "histories": [
-            {
-                "year": 2025,
-                "score": "489.0",
-                "plan": 15,
-                "enroll": 15,
-                "diff": -12,
-                "ruleContent": '语数外180(语100*0.6+数100*0.6+外100*0.6)+职业技能420(技能展示300*1.4)',
-                "application": 3.1,
-                "admission": 1
-            },
-            {
-                "year": 2024,
-                "score": "",
-                "plan": null,
-                "enroll": 20
-            },
-            {
-                "year": 2023,
-                "score": "504.0",
-                "plan": null,
-                "enroll": 32
-            }
-        ],
-        "skill": {
-            year: 2025,
-            cultureScore: 230,
-            cultureRule: "语数外",
-            enrollScore: 489,
-            skillScore: 259, // 反向测技能分
-            diff: 0 // 负数表示低于skillScore,正数高于
-        }
-    }
-    const bigData: VoluntaryDto = {data: data.value, model: model.value, result}
+    const {data: result} = await postRenderRules(target.value, model.value)
+    const bigData: VoluntaryDto = {target: target.value, rules: rules.value, model: model.value, result}
     transferTo(routes.voluntaryResult, {bigData})
 }
 
-onMounted(async () => {
-    // api get rules
-    await nextTick()
-    data.value = {
-        // code: "20949",
-        majorAncestors: "交通运输大类>铁道运输类",
-        majorId: "68526",
-        majorName: "铁道交通运营管理",
-        majorGroup: '专业组一',
-        // notice: "",
-        universityId: "20949",
-        universityLogo: "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/23b6da550a584ea6b60886c6ae97b610.jpg",
-        universityName: "湖南铁道职业技术学院",
-        rules: [{
-            category: '文化素质',
-            content: '语(100分)+数(100分)+外(100分)',
-            details: [{
-                enumRuleCategory: 'Enroll',
-                enumInputType: 'Score',
-                label: '语文',
-                options: ["100"],
-                fieldName: '语文',
-                required: true,
-                readonly: true,
-                defaultValue: 80
-            }, {
-                enumRuleCategory: 'Enroll',
-                enumInputType: 'Score',
-                label: '数学',
-                options: ["100"],
-                fieldName: '数学',
-                required: true,
-                defaultValue: 84
-            }, {
-                enumRuleCategory: 'Enroll',
-                enumInputType: 'Score',
-                label: '外语',
-                options: ["100"],
-                fieldName: '外语',
-                required: true,
-                defaultValue: 88
-            }]
-        }, {
-            category: '职业技能',
-            content: '机试(200分)+ 技能展示(100分)',
-            details: [{
-                enumRuleCategory: 'Enroll',
-                enumInputType: 'Score',
-                label: '笔试/机试',
-                options: ["200"],
-                fieldName: '笔试/机试',
-                required: true,
-                defaultValue: 180
-            }, {
-                enumRuleCategory: 'Enroll',
-                enumInputType: 'Score',
-                label: '技能展示',
-                options: ["100"],
-                fieldName: '技能展示',
-                required: true,
-                defaultValue: 81
-            }]
-        }]
-    }
-    // init model
-    data.value.rules.forEach((r) => {
-        r.details.forEach((d) => {
-            if (d.options?.length) {
-                model.value[d.fieldName] = d.defaultValue ? d.defaultValue : ''
-                model.value[d.fieldName + 'Total'] = d.options ? d.options[0] : null
-            }
-        })
-    })
-})
-
-provide(VOLUNTARY_FORM, data)
+provide(VOLUNTARY_TARGET, target)
+provide(VOLUNTARY_RULES, rules)
 provide(VOLUNTARY_MODEL, model)
 
 // 为了让子组件触发页面滚动
-onPageScroll(() => { })
+onPageScroll(() => {
+})
 </script>
 
 <style lang="scss">

+ 40 - 30
src/pagesStudy/pages/targeted-add/targeted-add.vue

@@ -1,6 +1,6 @@
 <template>
     <ie-page bg-color="#F6F8FA" :fix-height="true">
-        <ie-navbar title="添加定向院校"/>
+        <ie-navbar :title="title"/>
         <view class="mt-16 bg-white py-10">
             <view class="">
                 <uv-cell-group :border="false">
@@ -37,40 +37,40 @@
                 <ie-button type="primary" @click="handleAdd">确认</ie-button>
             </view>
         </ie-safe-toolbar>
-    </ie-page>
-    <ie-popup ref="popupRef" title="选择专业" @confirm="handleConfirm">
-        <view class="h-[50vh] bg-white px-30 pt-20 flex flex-col">
-            <view>
-                <uv-search v-model="keyword" shape="square" :showAction="false" placeholder="请输入专业名称"/>
-            </view>
-            <view class="mt-20 flex-1 min-h-1">
-                <scroll-view scroll-y class="h-full">
-                    <view v-for="item in filteredMajorList" :key="item.id"
-                          class="px-20 py-16 bg-white sibling-border-top flex items-center gap-x-20"
-                          @click="handleSelect(item)">
-                        <view class="flex-1 min-w-1 flex-shrink-0">
-                            <view class="flex items-center gap-x-10 text-fore-title">
+        <ie-popup ref="popupRef" title="选择专业" @confirm="handleConfirm">
+            <view class="h-[50vh] bg-white px-30 pt-20 flex flex-col">
+                <view>
+                    <uv-search v-model="keyword" shape="square" :showAction="false" placeholder="请输入专业名称"/>
+                </view>
+                <view class="mt-20 flex-1 min-h-1">
+                    <scroll-view scroll-y class="h-full">
+                        <view v-for="item in filteredMajorList" :key="item.id"
+                              class="px-20 py-16 bg-white sibling-border-top flex items-center gap-x-20"
+                              @click="handleSelect(item)">
+                            <view class="flex-1 min-w-1 flex-shrink-0">
+                                <view class="flex items-center gap-x-10 text-fore-title">
                                 <span class="text-30 " :class="[isActive(item) ? 'text-primary' : 'text-fore-title']">{{
                                         item.name
                                     }}</span>
-                                <span v-if="item.notice" class="text-22 text-fore-light flex-1 min-w-1 ellipsis-1"
-                                      :class="[isActive(item) ? 'text-primary' : 'text-fore-title']">{{
-                                        `(${item.notice})`
-                                    }}</span>
-                            </view>
-                            <view class="mt-6 text-22 text-fore-light"
-                                  :class="[isActive(item) ? 'text-primary' : 'text-fore-light']">
-                                {{
-                                    item.ancestors
-                                }}
+                                    <span v-if="item.notice" class="text-22 text-fore-light flex-1 min-w-1 ellipsis-1"
+                                          :class="[isActive(item) ? 'text-primary' : 'text-fore-title']">{{
+                                            `(${item.notice})`
+                                        }}</span>
+                                </view>
+                                <view class="mt-6 text-22 text-fore-light"
+                                      :class="[isActive(item) ? 'text-primary' : 'text-fore-light']">
+                                    {{
+                                        item.ancestors
+                                    }}
+                                </view>
                             </view>
+                            <uv-icon v-if="isActive(item)" name="checkmark" size="20" color="#31A0FC"/>
                         </view>
-                        <uv-icon v-if="isActive(item)" name="checkmark" size="20" color="#31A0FC"/>
-                    </view>
-                </scroll-view>
+                    </scroll-view>
+                </view>
             </view>
-        </view>
-    </ie-popup>
+        </ie-popup>
+    </ie-page>
 </template>
 
 <script lang="ts" setup>
@@ -79,9 +79,10 @@ import {DirectedSchool, SelectedUniversityMajor, University, UniversityMajor} fr
 import {getUniversityMajorList} from '@/api/modules/university';
 import {useUserStore} from '@/store/userStore';
 import {routes} from "@/common/routes";
+import {UniversityPickerPageOptions} from "@/types/transfer";
 
 const userStore = useUserStore();
-const {transferTo} = useTransferPage();
+const {prevData, transferTo, transferBack} = useTransferPage<UniversityPickerPageOptions, any>();
 const {directedSchoolList} = toRefs(userStore);
 const form = ref<Partial<SelectedUniversityMajor>>({});
 const keyword = ref('');
@@ -95,6 +96,7 @@ const majorList = ref<UniversityMajor[]>([]);
 const filteredMajorList = computed(() => {
     return majorList.value.filter(item => item.name.includes(keyword.value));
 });
+const title = computed(() => prevData.value.title || '添加定向院校')
 const handleUniversitySelect = () => {
     transferTo(routes.universityPicker).then((res: any) => {
         if (res) {
@@ -156,6 +158,14 @@ const handleAdd = async () => {
         uni.$ie.showToast('请选择专业');
         return;
     }
+    if (prevData.value.fromVoluntary === true) {
+        // 志愿类
+        if (prevData.value.selectedUniversityId === form.value.universityId &&
+            prevData.value.selectedMajorId === form.value.majorId) {
+            return uni.$ie.showToast('请勿选择相同院校专业')
+        }
+        return transferBack(form.value)
+    }
     // 检查数据是否已存在
     const historyData = directedSchoolList.value;
     const isExist = historyData.some(item => item.universityId === form.value.universityId && item.majorId === form.value.majorId);

+ 2 - 1
src/types/injectionSymbols.ts

@@ -45,7 +45,8 @@ export const CLOSE_VIP_POPUP = Symbol('CLOSE_VIP_POPUP') as InjectionKey<() => v
 /*
 * 计算录取概率
 * */
-export const VOLUNTARY_FORM = Symbol('VOLUNTARY_FORM') as InjectionKey<Ref<Voluntary.SelectedCollegeMajorWithRules>>
+export const VOLUNTARY_TARGET = Symbol('VOLUNTARY_TARGET') as InjectionKey<Ref<Study.SelectedUniversityMajor>>
+export const VOLUNTARY_RULES = Symbol('VOLUNTARY_RULES') as InjectionKey<Ref<Voluntary.EnrollRule[]>>
 export const VOLUNTARY_MODEL = Symbol('VOLUNTARY_MODEL') as InjectionKey<Ref<Voluntary.VoluntaryModel>>
 export const VOLUNTARY_RESULT = Symbol('VOLUNTARY_RESULT') as InjectionKey<Ref<Voluntary.VoluntaryResult>>
 

+ 3 - 3
src/types/transfer.ts

@@ -44,7 +44,7 @@ export interface SimulationAnalysisPageOptions {
 
 export interface UniversityPickerPageOptions {
   title?: string;
-  transferBack?: boolean;
-  selectedCollegeCode?: string;
-  selectedMajorCode?: string;
+  fromVoluntary?: boolean;
+  selectedUniversityId?: string|number;
+  selectedMajorId?: string|number;
 }

+ 8 - 9
src/types/voluntary.ts

@@ -1,5 +1,4 @@
-import {SelectedUniversityMajor} from "@/types/study";
-import {DictItem} from "@/types/index";
+import {DictItem, Study} from "@/types/index";
 
 export type EnumInputType = 'Score' | 'Number' | 'Text' | 'Radio' | 'Picker' | 'Checkbox' | 'Eyesight';
 export type EnumRuleCategory = 'Enroll' | 'Special';
@@ -29,15 +28,9 @@ export interface EnrollRuleItem {
 export interface EnrollRule {
     category: string;
     content: string;
-
     details: EnrollRuleItem[]
 }
 
-export interface SelectedCollegeMajorWithRules extends SelectedUniversityMajor {
-    majorGroup: string;
-    rules: EnrollRule[];
-}
-
 export interface VoluntaryModel extends Record<string, string | number | null> {
 
 }
@@ -77,8 +70,13 @@ export interface VoluntaryResult {
     "skill": VoluntaryResultSkill
 }
 
+export interface SelectedUniversityMajor extends Study.SelectedUniversityMajor {
+
+}
+
 export interface VoluntaryDto {
-    data: SelectedCollegeMajorWithRules;
+    target: SelectedUniversityMajor;
+    rules: EnrollRule[];
     model: VoluntaryModel;
     result: VoluntaryResult;
 }
@@ -97,6 +95,7 @@ export interface VoluntaryMajorItem {
     majorAncestors: string;
     majorGroup: string;
 }
+
 export interface VoluntaryRecord {
     id: number;
     universityLogo: string;