intention.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. import { ref, computed, onMounted, onUnmounted } from 'vue';
  2. import StepLayout from '../../components/step-layout/step-layout.vue';
  3. import { getDicts } from '../../api/dict';
  4. import { updateStudent, getStudent } from '../../api/student';
  5. export default {
  6. components: {
  7. StepLayout
  8. },
  9. setup() {
  10. const intentions = ref([]); // main_position_type 求职意向
  11. const arrivalTime = ref(''); // 当前选中的到岗时间 value
  12. const internDuration = ref(''); // 当前选中的实习时长 value
  13. const arrivalTimeList = ref([]); // 保存到岗时间字典完整列表
  14. const durationList = ref([]); // 保存实习时长字典完整列表
  15. const isIntern = computed(() => {
  16. return intentions.value.find(item => item.name === '实习')?.selected || false;
  17. });
  18. // 展示用的 label:将 value 反查为 dictLabel
  19. const arrivalTimeLabel = computed(() => {
  20. if (!arrivalTime.value) return '';
  21. const found = arrivalTimeList.value.find(d => d.dictValue === arrivalTime.value);
  22. return found ? found.dictLabel : arrivalTime.value;
  23. });
  24. const internDurationLabel = computed(() => {
  25. if (!internDuration.value) return '';
  26. const found = durationList.value.find(d => d.dictValue === internDuration.value);
  27. return found ? found.dictLabel : internDuration.value;
  28. });
  29. const jobTypes = ref([]); // main_position_intention 求职类型
  30. const targetCompanies = ref([]); // 选中的意向公司列表
  31. const showModal = ref(false);
  32. const modalContent = ref('');
  33. let currentDeleteIndex = -1;
  34. const isEditMode = ref(false);
  35. const loadDicts = async () => {
  36. uni.showLoading({ title: '加载中...' });
  37. try {
  38. const [arrRes, posTypeRes, posIntentionRes, durRes] = await Promise.all([
  39. getDicts('main_arrival_time'),
  40. getDicts('main_position_type'),
  41. getDicts('main_position_intention'),
  42. getDicts('main_internship_duration')
  43. ]);
  44. if (arrRes.code === 200) {
  45. arrivalTimeList.value = (arrRes.data || arrRes.rows || []);
  46. if(arrivalTimeList.value.length > 0) {
  47. arrivalTime.value = arrivalTimeList.value[1]?.dictValue || arrivalTimeList.value[0]?.dictValue || '';
  48. }
  49. }
  50. if (durRes && durRes.code === 200) {
  51. durationList.value = (durRes.data || durRes.rows || []);
  52. if (durationList.value.length > 0) {
  53. internDuration.value = durationList.value[0]?.dictValue || '';
  54. }
  55. }
  56. if (posTypeRes.code === 200) {
  57. intentions.value = (posTypeRes.data || posTypeRes.rows || []).map((dict, idx) => ({
  58. name: dict.dictLabel,
  59. value: dict.dictValue,
  60. selected: idx === 0
  61. }));
  62. }
  63. if (posIntentionRes.code === 200) {
  64. jobTypes.value = (posIntentionRes.data || posIntentionRes.rows || []).map((dict, idx) => ({
  65. name: dict.dictLabel,
  66. value: dict.dictValue,
  67. selected: idx < 2 // 默认随便选一两个
  68. }));
  69. }
  70. } catch (e) {
  71. console.error(e);
  72. } finally {
  73. uni.hideLoading();
  74. }
  75. };
  76. const loadStudentData = async () => {
  77. const userInfo = uni.getStorageSync('userInfo');
  78. if (!userInfo || !userInfo.studentId) return;
  79. try {
  80. const res = await getStudent(userInfo.studentId);
  81. if (res.code === 200 && res.data) {
  82. const data = res.data;
  83. // 回显到岗时间 —— 兼容 value 和 label
  84. if (data.availability) {
  85. const found = arrivalTimeList.value.find(d => d.dictValue === data.availability || d.dictLabel === data.availability);
  86. if (found) arrivalTime.value = found.dictValue;
  87. }
  88. // 回显实习时长 —— 兼容 value 和 label
  89. if (data.internshipDuration) {
  90. const found = durationList.value.find(d => d.dictValue === data.internshipDuration || d.dictLabel === data.internshipDuration);
  91. if (found) internDuration.value = found.dictValue;
  92. }
  93. // 回显求职类型(全职/实习/兼职)—— 兼容 label 和 value
  94. if (data.jobType) {
  95. intentions.value.forEach(item => {
  96. item.selected = (item.value === data.jobType || item.name === data.jobType);
  97. });
  98. }
  99. // 回显求职意向(从 jobIntention 字段解析)—— 兼容 label 和 value
  100. if (data.jobIntention) {
  101. const selectedIntentions = data.jobIntention.split(',').map(s => s.trim()).filter(s => s);
  102. jobTypes.value.forEach(item => {
  103. item.selected = selectedIntentions.includes(item.value) || selectedIntentions.includes(item.name);
  104. });
  105. }
  106. // 回显意向公司
  107. if (data.intentionCompanies) {
  108. const companyNames = data.intentionCompanies.split(',').map(s => s.trim()).filter(s => s);
  109. targetCompanies.value = companyNames.map(name => ({ name }));
  110. }
  111. }
  112. } catch (err) {
  113. console.error('加载学员数据失败', err);
  114. }
  115. };
  116. onMounted(async () => {
  117. const options = getCurrentPages()[getCurrentPages().length - 1].options;
  118. if (options && options.editMode === '1') {
  119. isEditMode.value = true;
  120. }
  121. uni.$on('submit_companies', (selectedCompanies) => {
  122. targetCompanies.value = [...selectedCompanies];
  123. });
  124. await loadDicts();
  125. // 如果是编辑模式,加载学员数据进行回显
  126. if (isEditMode.value) {
  127. await loadStudentData();
  128. }
  129. });
  130. onUnmounted(() => {
  131. uni.$off('submit_companies');
  132. });
  133. const openModal = (content, index) => {
  134. modalContent.value = content;
  135. currentDeleteIndex = index;
  136. showModal.value = true;
  137. };
  138. const closeModal = () => {
  139. showModal.value = false;
  140. };
  141. const confirmDelete = () => {
  142. if (currentDeleteIndex !== -1) {
  143. targetCompanies.value.splice(currentDeleteIndex, 1);
  144. }
  145. closeModal();
  146. };
  147. const toggleIntention = (index) => {
  148. intentions.value.forEach((item, i) => {
  149. item.selected = (i === index);
  150. });
  151. };
  152. const selectInternDuration = () => {
  153. if (durationList.value.length === 0) return;
  154. uni.showActionSheet({
  155. itemList: durationList.value.map(d => d.dictLabel),
  156. success: (res) => {
  157. internDuration.value = durationList.value[res.tapIndex].dictValue;
  158. }
  159. });
  160. };
  161. const selectTime = () => {
  162. if (arrivalTimeList.value.length === 0) return;
  163. uni.showActionSheet({
  164. itemList: arrivalTimeList.value.map(d => d.dictLabel),
  165. success: (res) => {
  166. arrivalTime.value = arrivalTimeList.value[res.tapIndex].dictValue;
  167. }
  168. });
  169. };
  170. const toggleType = (index) => {
  171. jobTypes.value[index].selected = !jobTypes.value[index].selected;
  172. };
  173. const addCompany = () => {
  174. const selectedNames = targetCompanies.value.map(c => c.name);
  175. uni.setStorageSync('selected_companies', JSON.stringify(selectedNames));
  176. uni.navigateTo({ url: '/pages/intention/company-select' });
  177. };
  178. const deleteCompany = (index) => {
  179. openModal('确定要删除这家意向公司吗?', index);
  180. };
  181. const onSubmit = async () => {
  182. console.log('intention.js: onSubmit called');
  183. uni.showLoading({ title: '提交中...' });
  184. try {
  185. const userInfo = uni.getStorageSync('userInfo');
  186. console.log('intention.js: userInfo from storage:', userInfo);
  187. const studentId = userInfo ? (userInfo.studentId || userInfo.id) : null;
  188. console.log('intention.js: studentId identified:', studentId);
  189. if (!studentId) {
  190. uni.hideLoading();
  191. uni.showToast({ title: '登录状态失效', icon: 'none' });
  192. return;
  193. }
  194. const selectedJobIntention = intentions.value.find(i => i.selected)?.value || '';
  195. const selectedJobType = jobTypes.value.filter(i => i.selected).map(i => i.value).join(',');
  196. const companies = targetCompanies.value.map(c => c.name).join(',');
  197. // 构建更新数据
  198. const reqData = {
  199. id: studentId,
  200. jobIntention: selectedJobType, // 求职意向类型(审计、咨询、税务等),传 dictValue
  201. intentionCompanies: companies, // 意向公司列表
  202. jobType: selectedJobIntention, // 求职类型(全职、实习、兼职),传 dictValue
  203. availability: arrivalTime.value,
  204. internshipDuration: isIntern.value ? internDuration.value : ''
  205. };
  206. console.log('intention.js: sending updateStudent request with data:', reqData);
  207. const res = await updateStudent(reqData);
  208. console.log('intention.js: updateStudent response:', res);
  209. uni.hideLoading();
  210. if (res.code === 200) {
  211. uni.showToast({
  212. title: isEditMode.value ? '保存成功' : '提交成功',
  213. icon: 'success'
  214. });
  215. setTimeout(() => {
  216. uni.reLaunch({
  217. url: '/pages/my/my',
  218. success: () => {
  219. setTimeout(() => {
  220. uni.navigateTo({ url: '/pages/my/resume_view' });
  221. }, 100);
  222. }
  223. });
  224. }, 1000);
  225. } else {
  226. uni.showToast({ title: res.msg || '保存失败', icon: 'none' });
  227. }
  228. } catch (e) {
  229. console.error(e);
  230. uni.hideLoading();
  231. uni.showToast({ title: '网络异常', icon: 'none' });
  232. }
  233. };
  234. const onSkip = () => {
  235. uni.reLaunch({
  236. url: '/pages/my/my',
  237. success: () => {
  238. setTimeout(() => {
  239. uni.navigateTo({ url: '/pages/my/resume_view' });
  240. }, 100);
  241. }
  242. });
  243. };
  244. return {
  245. intentions,
  246. arrivalTime,
  247. arrivalTimeLabel,
  248. internDuration,
  249. internDurationLabel,
  250. isIntern,
  251. jobTypes,
  252. targetCompanies,
  253. showModal, modalContent, closeModal, confirmDelete,
  254. toggleIntention,
  255. selectTime,
  256. selectInternDuration,
  257. toggleType,
  258. addCompany, deleteCompany,
  259. onSubmit, onSkip,
  260. isEditMode
  261. };
  262. }
  263. }