add-education.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. import { ref, computed } from 'vue';
  2. import { onLoad } from '@dcloudio/uni-app';
  3. import { addStudentEducation, updateStudentEducation } from '../../api/studentEducation';
  4. import { getDicts } from '../../api/dict';
  5. export default {
  6. setup() {
  7. // 从字典接口获取选项,初始化为空数组
  8. const degreeOptions = ref([]);
  9. const typeOptions = ref([]);
  10. const form = ref({
  11. school: '',
  12. degree: '',
  13. educationType: '',
  14. major: '',
  15. startTime: '',
  16. endTime: '',
  17. desc: ''
  18. });
  19. // "Wait for complete" logic: mandatory fields
  20. const isComplete = computed(() => {
  21. return !!(form.value.school &&
  22. form.value.degree &&
  23. form.value.major &&
  24. form.value.startTime &&
  25. form.value.endTime);
  26. });
  27. const editIndex = ref(-1);
  28. const isEdit = computed(() => editIndex.value !== -1);
  29. // 加载字典数据
  30. const loadDicts = async () => {
  31. try {
  32. const [eduRes, typeRes] = await Promise.all([
  33. getDicts('main_education'),
  34. getDicts('main_education_all')
  35. ]);
  36. degreeOptions.value = (eduRes.data || []).map(item => item.dictLabel);
  37. typeOptions.value = (typeRes.data || []).map(item => item.dictLabel);
  38. // 设置默认值
  39. if (!form.value.educationType && typeOptions.value.length > 0) {
  40. form.value.educationType = typeOptions.value[0];
  41. }
  42. } catch (e) {
  43. console.error('加载字典失败', e);
  44. }
  45. };
  46. onLoad((options) => {
  47. loadDicts();
  48. if (options && options.index !== undefined) {
  49. editIndex.value = parseInt(options.index);
  50. const data = uni.getStorageSync('edit_data_education');
  51. if (data) {
  52. // 映射后端字段到表单字段
  53. // education 字段可能是 "本科 统招" 格式(旧数据),也可能是纯 "本科"(新数据)
  54. let degreeVal = data.education || data.degree || '';
  55. let typeVal = '';
  56. if (degreeVal.includes(' ')) {
  57. // 旧格式 "本科 统招",拆分
  58. const parts = degreeVal.split(' ');
  59. degreeVal = parts[0];
  60. typeVal = parts[1] || '';
  61. }
  62. // 优先使用独立字段 educationType
  63. if (data.educationType) {
  64. typeVal = data.educationType;
  65. }
  66. form.value = {
  67. id: data.id,
  68. school: data.school || '',
  69. degree: degreeVal,
  70. educationType: typeVal,
  71. major: data.major || '',
  72. startTime: data.startTime || '',
  73. endTime: data.endTime || '',
  74. desc: data.campusExperience || data.desc || ''
  75. };
  76. }
  77. }
  78. uni.setNavigationBarTitle({ title: isEdit.value ? '修改教育经历' : '添加教育经历' });
  79. });
  80. const goBack = () => {
  81. uni.navigateBack();
  82. };
  83. const showPicker = ref(false);
  84. const pickerValue = ref([0, 0]);
  85. const openPicker = () => {
  86. if (form.value.degree) {
  87. let dIdx = degreeOptions.value.indexOf(form.value.degree);
  88. let tIdx = typeOptions.value.indexOf(form.value.educationType);
  89. if (dIdx === -1) dIdx = 0;
  90. if (tIdx === -1) tIdx = 0;
  91. pickerValue.value = [dIdx, tIdx];
  92. } else {
  93. pickerValue.value = [0, 0];
  94. }
  95. showPicker.value = true;
  96. };
  97. const closePicker = () => {
  98. showPicker.value = false;
  99. };
  100. const onPickerChange = (e) => {
  101. pickerValue.value = e.detail.value;
  102. };
  103. const confirmPicker = () => {
  104. const dIdx = pickerValue.value[0] !== undefined ? pickerValue.value[0] : 0;
  105. const tIdx = pickerValue.value[1] !== undefined ? pickerValue.value[1] : 0;
  106. if (degreeOptions.value.length > 0) {
  107. form.value.degree = degreeOptions.value[dIdx];
  108. }
  109. if (typeOptions.value.length > 0) {
  110. form.value.educationType = typeOptions.value[tIdx];
  111. }
  112. showPicker.value = false;
  113. };
  114. const yearOptions = [];
  115. const monthOptions = [];
  116. const currentYear = new Date().getFullYear();
  117. for (let i = 1990; i <= currentYear + 10; i++) {
  118. yearOptions.push(i + '年');
  119. }
  120. for (let i = 1; i <= 12; i++) {
  121. monthOptions.push((i < 10 ? '0' + i : i) + '月');
  122. }
  123. const showDatePicker = ref(false);
  124. const datePickerType = ref('start'); // 'start' or 'end'
  125. const datePickerValue = ref([currentYear - 1990, 0]); // 默认当前年 1月
  126. const openDatePicker = (type) => {
  127. datePickerType.value = type;
  128. const target = type === 'start' ? form.value.startTime : form.value.endTime;
  129. if (target) {
  130. const parts = target.split('.');
  131. let yIdx = yearOptions.indexOf(parts[0] + '年');
  132. let mIdx = monthOptions.indexOf(parts[1] + '月');
  133. if (yIdx === -1) yIdx = currentYear - 1990;
  134. if (mIdx === -1) mIdx = 0;
  135. datePickerValue.value = [yIdx, mIdx];
  136. } else {
  137. datePickerValue.value = [currentYear - 1990, 0];
  138. }
  139. showDatePicker.value = true;
  140. };
  141. const closeDatePicker = () => {
  142. showDatePicker.value = false;
  143. };
  144. const onDatePickerChange = (e) => {
  145. datePickerValue.value = e.detail.value;
  146. };
  147. const confirmDatePicker = () => {
  148. const yIdx = datePickerValue.value[0] !== undefined ? datePickerValue.value[0] : (currentYear - 1990);
  149. const mIdx = datePickerValue.value[1] !== undefined ? datePickerValue.value[1] : 0;
  150. const yVal = yearOptions[yIdx].replace('年', '');
  151. const mVal = monthOptions[mIdx].replace('月', '');
  152. const formatted = `${yVal}.${mVal}`;
  153. if (datePickerType.value === 'start') {
  154. form.value.startTime = formatted;
  155. } else {
  156. form.value.endTime = formatted;
  157. }
  158. showDatePicker.value = false;
  159. };
  160. const saveForm = async () => {
  161. if (!isComplete.value) return;
  162. uni.showLoading({ title: '保存中...' });
  163. try {
  164. // 读取当前登录学员
  165. const userInfo = uni.getStorageSync('userInfo');
  166. const studentId = userInfo ? userInfo.studentId : null;
  167. if (!studentId) {
  168. uni.hideLoading();
  169. uni.showToast({ title: '登录失效,请重新登录', icon: 'none' });
  170. return;
  171. }
  172. // 拼装后端需要的数据格式 (MainStudentEducationBo)
  173. const reqData = {
  174. studentId: studentId,
  175. school: form.value.school,
  176. education: form.value.degree,
  177. educationType: form.value.educationType,
  178. major: form.value.major,
  179. startTime: form.value.startTime,
  180. endTime: form.value.endTime,
  181. campusExperience: form.value.desc
  182. };
  183. if (isEdit.value) {
  184. reqData.id = form.value.id; // 如果是修改模式,需要附加主键 ID
  185. const res = await updateStudentEducation(reqData);
  186. uni.hideLoading();
  187. if (res.code === 200) {
  188. uni.showToast({ title: '修改成功', icon: 'success' });
  189. uni.removeStorageSync('edit_data_education');
  190. setTimeout(() => {
  191. uni.$emit('refresh_experience'); // 传给外层让它再次加载数据
  192. uni.navigateBack();
  193. }, 1000);
  194. } else {
  195. uni.showToast({ title: res.msg || '修改失败', icon: 'none' });
  196. }
  197. } else {
  198. const res = await addStudentEducation(reqData);
  199. uni.hideLoading();
  200. if (res.code === 200) {
  201. uni.showToast({ title: '添加成功', icon: 'success' });
  202. setTimeout(() => {
  203. // 通知上一个页面数据已经更新
  204. uni.$emit('refresh_experience');
  205. uni.navigateBack();
  206. }, 1000);
  207. } else {
  208. uni.showToast({ title: res.msg || '添加失败', icon: 'none' });
  209. }
  210. }
  211. } catch (error) {
  212. uni.hideLoading();
  213. uni.showToast({ title: '网络异常,保存失败', icon: 'none' });
  214. console.error(error);
  215. }
  216. };
  217. return {
  218. form,
  219. degreeOptions,
  220. typeOptions,
  221. isComplete,
  222. isEdit,
  223. goBack,
  224. showPicker,
  225. pickerValue,
  226. openPicker,
  227. closePicker,
  228. onPickerChange,
  229. confirmPicker,
  230. showDatePicker,
  231. datePickerType,
  232. datePickerValue,
  233. yearOptions,
  234. monthOptions,
  235. openDatePicker,
  236. closeDatePicker,
  237. onDatePickerChange,
  238. confirmDatePicker,
  239. saveForm
  240. };
  241. }
  242. }