targeted-add.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <template>
  2. <ie-page bg-color="#F6F8FA" :fix-height="true">
  3. <ie-navbar :title="title" />
  4. <view class="mt-16 bg-white py-10">
  5. <view class="">
  6. <uv-cell-group :border="false">
  7. <uv-cell isLink :border="true" :cellStyle="cellStyle" :rightIconStyle="rightIconStyle"
  8. @click="handleUniversitySelect">
  9. <template #title>
  10. <text class="text-30 text-fore-subtitle whitespace-nowrap">选择院校</text>
  11. </template>
  12. <template #value>
  13. <text v-if="form.universityName" class="mx-10 text-30 text-fore-title">
  14. {{ form.universityName }}
  15. </text>
  16. <text v-else class="mr-10 text-30 text-fore-placeholder">请选择</text>
  17. </template>
  18. </uv-cell>
  19. <uv-cell isLink :border="false" :cellStyle="cellStyle" :rightIconStyle="rightIconStyle"
  20. @click="handleMajorSelect">
  21. <template #title>
  22. <text class="text-30 text-fore-subtitle whitespace-nowrap">选择专业</text>
  23. </template>
  24. <template #value>
  25. <text v-if="form.majorName" class="mx-10 text-30 text-fore-title">
  26. {{ form.majorName }}
  27. </text>
  28. <text v-else class="mr-10 text-30 text-fore-placeholder">请选择</text>
  29. </template>
  30. </uv-cell>
  31. </uv-cell-group>
  32. </view>
  33. </view>
  34. <ie-safe-toolbar :height="84" :shadow="false">
  35. <view class="px-46 pt-24">
  36. <ie-button type="primary" @click="handleAdd">确认</ie-button>
  37. </view>
  38. </ie-safe-toolbar>
  39. <ie-popup ref="popupRef" title="选择专业" @confirm="handleConfirm">
  40. <view class="h-[50vh] bg-white px-30 pt-20 flex flex-col">
  41. <view>
  42. <uv-search v-model="keyword" shape="square" :showAction="false" placeholder="请输入专业名称" />
  43. </view>
  44. <view class="mt-20 flex-1 min-h-1">
  45. <scroll-view scroll-y class="h-full">
  46. <view v-for="item in filteredMajorList" :key="item.id"
  47. class="px-20 py-16 bg-white sibling-border-top flex items-center gap-x-20" @click="handleSelect(item)">
  48. <view class="flex-1 min-w-1 flex-shrink-0">
  49. <view class="flex items-center gap-x-10 text-fore-title">
  50. <span class="text-30 " :class="[isActive(item) ? 'text-primary' : 'text-fore-title']">{{
  51. item.name
  52. }}</span>
  53. <span v-if="item.notice" class="text-22 text-fore-light flex-1 min-w-1 ellipsis-1"
  54. :class="[isActive(item) ? 'text-primary' : 'text-fore-title']">{{
  55. `(${item.notice})`
  56. }}</span>
  57. </view>
  58. <view class="mt-6 text-22 text-fore-light"
  59. :class="[isActive(item) ? 'text-primary' : 'text-fore-light']">
  60. {{
  61. item.ancestors
  62. }}
  63. </view>
  64. </view>
  65. <uv-icon v-if="isActive(item)" name="checkmark" size="20" color="#31A0FC" />
  66. </view>
  67. </scroll-view>
  68. </view>
  69. </view>
  70. </ie-popup>
  71. </ie-page>
  72. </template>
  73. <script lang="ts" setup>
  74. import { useTransferPage } from '@/hooks/useTransferPage';
  75. import { University } from '@/types/university';
  76. import { DirectedSchool, UniversityMajor } from '@/types/study';
  77. import { SelectedUniversityMajor } from '@/types/voluntary';
  78. import { getUniversityMajorList } from '@/api/modules/university';
  79. import { useUserStore } from '@/store/userStore';
  80. import { routes } from "@/common/routes";
  81. import { UniversityPickerPageOptions } from "@/types/transfer";
  82. const userStore = useUserStore();
  83. const { prevData, transferTo, transferBack } = useTransferPage<UniversityPickerPageOptions, any>();
  84. const { directedSchoolList } = toRefs(userStore);
  85. const form = ref<Partial<SelectedUniversityMajor>>({});
  86. const keyword = ref('');
  87. const cellStyle = {
  88. padding: '20rpx 40rpx'
  89. }
  90. const rightIconStyle = {
  91. fontSize: '14px'
  92. }
  93. const majorList = ref<UniversityMajor[]>([]);
  94. const filteredMajorList = computed(() => {
  95. return majorList.value.filter(item => item.name.includes(keyword.value));
  96. });
  97. const title = computed(() => prevData.value.title || '添加定向院校')
  98. const handleUniversitySelect = () => {
  99. transferTo(routes.universityPicker).then((res: any) => {
  100. if (res) {
  101. const university = res as University;
  102. if (university.code !== form.value.universityId) {
  103. selectedMajor.value = null;
  104. form.value.majorId = '';
  105. form.value.majorName = '';
  106. }
  107. form.value.universityId = university.code;
  108. form.value.universityName = university.name;
  109. form.value.universityLogo = university.logo;
  110. form.value.info = university;
  111. loadMajorList(university.code);
  112. }
  113. });
  114. }
  115. const popupRef = ref();
  116. const selectedMajor = ref<Pick<UniversityMajor, 'ancestors' | 'code' | 'id' | 'name'> | null>(null);
  117. const handleMajorSelect = () => {
  118. if (!form.value.universityId) {
  119. uni.$ie.showToast('请选择院校');
  120. return;
  121. }
  122. keyword.value = '';
  123. if (form.value.majorId) {
  124. selectedMajor.value = {
  125. ancestors: form.value.majorAncestors || '',
  126. code: form.value.majorId || '',
  127. id: Number(form.value.majorId),
  128. name: form.value.majorName || ''
  129. }
  130. } else {
  131. selectedMajor.value = null;
  132. }
  133. popupRef.value.open();
  134. }
  135. const handleConfirm = () => {
  136. if (!selectedMajor.value) {
  137. uni.$ie.showToast('请选择专业');
  138. return;
  139. }
  140. form.value.majorAncestors = selectedMajor.value.ancestors;
  141. form.value.majorId = selectedMajor.value.id.toString();
  142. form.value.majorName = selectedMajor.value.name;
  143. popupRef.value.close();
  144. }
  145. const handleSelect = (item: UniversityMajor) => {
  146. selectedMajor.value = item;
  147. }
  148. const handleAdd = async () => {
  149. if (!form.value.universityId) {
  150. uni.$ie.showToast('请选择院校');
  151. return;
  152. }
  153. if (!form.value.majorId) {
  154. uni.$ie.showToast('请选择专业');
  155. return;
  156. }
  157. if (prevData.value.fromVoluntary === true) {
  158. // 志愿类
  159. if (prevData.value.selectedUniversityId === form.value.universityId &&
  160. prevData.value.selectedMajorId === form.value.majorId) {
  161. return uni.$ie.showToast('请勿选择相同院校专业')
  162. }
  163. return transferBack(form.value)
  164. }
  165. // 检查数据是否已存在
  166. const historyData = directedSchoolList.value;
  167. const isExist = historyData.some(item => item.universityId === form.value.universityId && item.majorId === form.value.majorId);
  168. if (isExist) {
  169. uni.$ie.showToast('该院校专业已存在');
  170. return;
  171. }
  172. uni.$ie.showLoading();
  173. const params = {
  174. ...form.value,
  175. code: form.value.universityId
  176. } as DirectedSchool;
  177. await userStore.saveDirectedSchoolList([params, ...directedSchoolList.value]);
  178. uni.$ie.hideLoading();
  179. uni.$ie.showSuccess('保存成功');
  180. setTimeout(() => {
  181. transferTo('/pagesStudy/pages/targeted-setting/targeted-setting', {
  182. type: 'redirectTo'
  183. });
  184. }, 600);
  185. }
  186. const isActive = (item: UniversityMajor) => {
  187. return selectedMajor.value && selectedMajor.value.id === item.id;
  188. }
  189. const loadMajorList = async (universityId: string) => {
  190. uni.$ie.showLoading();
  191. const { data } = await getUniversityMajorList({ universityId });
  192. majorList.value = data;
  193. uni.$ie.hideLoading();
  194. }
  195. onLoad(() => {
  196. handleUniversitySelect();
  197. });
  198. </script>
  199. <style lang="scss" scoped></style>