college-major-picker.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <template>
  2. <num-common-card :num="num">
  3. <template #header>
  4. <view v-if="model.university.code" class="fx-row flex-1">
  5. <college-item :item="model.university" hidden-logo hidden-address class="flex-1"/>
  6. <horizontal-button :id="collegePickerId" icon="share-square" text="修改" @click="openCollegePicker"/>
  7. </view>
  8. <view v-else class="p-20">
  9. <uv-button size="small" :id="collegePickerId" type="primary" plain text="添加院校" icon="plus"
  10. icon-color="primary" @click="openCollegePicker"/>
  11. </view>
  12. </template>
  13. <view class="fx-col px-20 pb-30" :id="majorPickerId">
  14. <uv-cell v-for="idx in 4" :key="idx" :title="`专业 `+idx" is-link @click="openMajorPicker">
  15. <template #value>
  16. <text v-if="!model.majors[idx-1]" class="text-light">请选择专业</text>
  17. <view v-else class="text-primary fx-col items-end">
  18. <text>{{ model.majors[idx - 1].name }}</text>
  19. <text class="text-primary-light text-2xs">{{ model.majors[idx - 1].majorDirection }}</text>
  20. </view>
  21. </template>
  22. </uv-cell>
  23. </view>
  24. <view class="px-20 pb-30">
  25. <ai-form ref="aiForm" :model="model" :id-prefix="model.num" :render-rules="renderRules"
  26. :render-rule-loading="renderRuleLoading"/>
  27. </view>
  28. <major-picker ref="majorPicker" :university-code="model.university.code" :majors="model.majors"
  29. :limit="majorLimit" :major-category="form.majorCategory" @confirm="confirmMajors"/>
  30. </num-common-card>
  31. </template>
  32. <script>
  33. import {computed, ref, watch} from 'vue';
  34. import _ from 'lodash';
  35. import MajorPicker from "@/pages/ie/components/picker/major-picker.vue";
  36. import NumCommonCard from "@/pages/ie/entry-analysis/components/num-common-card.vue";
  37. import HorizontalButton from "@/pages/ie/components/horizontal-button.vue";
  38. import CollegeItem from "@/pages/college-library/components/college-item.vue";
  39. import AiForm from "@/pages/ie/components/ai-form/ai-form.vue";
  40. import MxConst from "@/common/MxConst";
  41. import {confirmAsync} from "@/utils/uni-helper";
  42. import {toast} from "@/uni_modules/uv-ui-tools/libs/function";
  43. import {useAIRenderRules} from "@/pages/ie/hooks/useAIRenderRules";
  44. import {useTransfer} from "@/hooks/useTransfer";
  45. import {useInjectAnalysisDataService} from "@/pages/ie/entry-analysis/components/useAnalysisDataInjection";
  46. export default {
  47. name: "college-major-picker",
  48. components: {CollegeItem, AiForm, HorizontalButton, NumCommonCard, MajorPicker},
  49. props: {
  50. num: {
  51. type: Number,
  52. default: 0
  53. },
  54. majorLimit: {
  55. type: Number,
  56. default: 4
  57. }
  58. },
  59. setup(props) {
  60. const {form} = useInjectAnalysisDataService()
  61. const lessMajorConfirmed = ref(false)
  62. const model = computed(() => form.value.universities[props.num])
  63. const majorCodes = computed(() => model.value.majors.map(m => m.code))
  64. const majorEnrollCodes = computed(() => model.value.majors.map(m => m.enrollCode))
  65. const aiForm = ref(null)
  66. const majorPicker = ref(null)
  67. const paramFactory = () => {
  68. const codes = majorCodes.value.sort()
  69. const enrollCodes = majorEnrollCodes.value.sort()
  70. if (!codes.length || !enrollCodes.length) return null
  71. return {
  72. renderType: MxConst.enum.ai.renderType.def,
  73. universityCode: model.value.university.code,
  74. majorCodes: codes,
  75. majorEnrollCodes: enrollCodes
  76. }
  77. }
  78. const {
  79. renderRules,
  80. renderRuleLoading,
  81. reloadRenderRules,
  82. validateRenderRule
  83. } = useAIRenderRules(paramFactory)
  84. const {transferTo, onPageCallback} = useTransfer()
  85. const pickerExcepts = computed(() => {
  86. return form.value.universities
  87. .filter(m => m != model.value)
  88. .map(m => m.university?.code)
  89. .filter(c => c)
  90. })
  91. const collegePickerId = computed(() => 'picker_college_' + props.num)
  92. const majorPickerId = computed(() => 'picker_major_' + props.num)
  93. const openCollegePicker = () => {
  94. if (!form.value.majorCategory) return toast('请先选择专业种类')
  95. const next = {
  96. majorCategory: form.value.majorCategory,
  97. excepts: pickerExcepts.value,
  98. callback: MxConst.globalEvents.collegeSelected
  99. }
  100. transferTo('/pages/college-library/picker/picker', next)
  101. }
  102. const openMajorPicker = () => {
  103. if (!model.value.university.code) return toast('请先添加院校')
  104. majorPicker.value.open()
  105. }
  106. const confirmMajors = (e) => {
  107. model.value.majors = e || []
  108. }
  109. const scrollToSelf = (id) => {
  110. const dom = document.getElementById(id)
  111. if (dom) dom.scrollIntoView(MxConst.scrollIntoOption)
  112. }
  113. const validate = async () => {
  114. if (!model.value.university?.code) {
  115. const err = `请给志愿${model.value.num + 1}添加院校`
  116. toast(err)
  117. scrollToSelf(collegePickerId.value)
  118. return Promise.reject(err)
  119. }
  120. if (!model.value.majors?.length) {
  121. const err = `请给志愿${model.value.num + 1}添加专业`
  122. toast(err)
  123. scrollToSelf(majorPickerId.value)
  124. return Promise.reject(err)
  125. }
  126. if (model.value.majors.length < props.majorLimit && !lessMajorConfirmed.value) {
  127. try {
  128. await confirmAsync(`志愿${model.value.num + 1}选择的专业不足${props.majorLimit}个,是否继续?!`)
  129. lessMajorConfirmed.value = true
  130. } catch (e) {
  131. scrollToSelf(majorPickerId.value)
  132. return Promise.reject(e)
  133. }
  134. }
  135. await validateRenderRule()
  136. return aiForm.value.validate()
  137. }
  138. onPageCallback((college) => {
  139. if (!college) return
  140. if (model.value.university?.code == college.code) return
  141. model.value.university = college
  142. model.value.majors = [] // reset majors
  143. renderRules.value = []
  144. lessMajorConfirmed.value = false
  145. })
  146. watch(() => form.value.majorCategory, () => {
  147. model.value.university = {}
  148. model.value.majors = []
  149. renderRules.value = []
  150. })
  151. watch(() => majorEnrollCodes.value.sort().toString(), () => {
  152. renderRules.value = []
  153. reloadRenderRules()
  154. })
  155. return {
  156. aiForm,
  157. majorPicker,
  158. form,
  159. model,
  160. lessMajorConfirmed,
  161. collegePickerId,
  162. majorPickerId,
  163. renderRules,
  164. renderRuleLoading,
  165. openCollegePicker,
  166. openMajorPicker,
  167. confirmMajors,
  168. validate
  169. }
  170. }
  171. }
  172. </script>
  173. <style scoped lang="scss">
  174. </style>