jobs.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. "use strict";
  2. const common_vendor = require("../../common/vendor.js");
  3. const common_assets = require("../../common/assets.js");
  4. const api_position = require("../../api/position.js");
  5. const api_dict = require("../../api/dict.js");
  6. if (!Math) {
  7. CustomTabbar();
  8. }
  9. const CustomTabbar = () => "../../components/custom-tabbar/custom-tabbar.js";
  10. const _sfc_main = {
  11. __name: "jobs",
  12. setup(__props) {
  13. const getStudentId = () => {
  14. const userInfo = common_vendor.index.getStorageSync("userInfo");
  15. if (!userInfo)
  16. return null;
  17. const id = userInfo.id || userInfo.studentId || null;
  18. common_vendor.index.__f__("log", "at pages/jobs/jobs.vue:172", "[getStudentId] userInfo:", JSON.stringify(userInfo), "=> id:", id);
  19. return id;
  20. };
  21. const statusBarHeight = common_vendor.ref(20);
  22. const titleBarMargin = common_vendor.ref(8);
  23. const menuButtonHeight = common_vendor.ref(32);
  24. const keyword = common_vendor.ref("");
  25. const sortType = common_vendor.ref("comprehensive");
  26. const currentJobType = common_vendor.ref(0);
  27. const jobTypeTabs = common_vendor.ref(["全部"]);
  28. const jobTypeValue = common_vendor.ref([""]);
  29. const loadDicts = () => {
  30. api_dict.getDicts("main_position_type").then((res) => {
  31. if (res.data && res.data.length > 0) {
  32. jobTypeTabs.value = ["全部岗位", ...res.data.map((item) => item.dictLabel)];
  33. jobTypeValue.value = ["", ...res.data.map((item) => item.dictValue)];
  34. } else {
  35. jobTypeTabs.value = ["全部岗位", "全职", "实习", "兼职"];
  36. jobTypeValue.value = ["", "0", "1", "2"];
  37. }
  38. fetchJobs(true);
  39. });
  40. };
  41. const jobList = common_vendor.ref([]);
  42. const pageNum = common_vendor.ref(1);
  43. const pageSize = common_vendor.ref(10);
  44. const hasMore = common_vendor.ref(true);
  45. const isLoading = common_vendor.ref(false);
  46. const showPopup = common_vendor.ref(false);
  47. const activeJob = common_vendor.ref(null);
  48. const openFeedbackPopup = (job) => {
  49. activeJob.value = job;
  50. showPopup.value = true;
  51. };
  52. const closePopup = () => {
  53. showPopup.value = false;
  54. };
  55. const handleDislikePosition = () => {
  56. if (!activeJob.value)
  57. return;
  58. const studentId = getStudentId();
  59. const job = activeJob.value;
  60. closePopup();
  61. jobList.value = jobList.value.filter((item) => item.id !== job.id);
  62. if (studentId) {
  63. api_position.dislikePosition(studentId, job.id).catch(() => {
  64. });
  65. }
  66. common_vendor.index.showToast({ title: "已屏蔽该岗位", icon: "none" });
  67. };
  68. const handleDislikeCompany = () => {
  69. if (!activeJob.value)
  70. return;
  71. const studentId = getStudentId();
  72. const job = activeJob.value;
  73. closePopup();
  74. jobList.value = jobList.value.filter((item) => item.rawTenantId !== job.rawTenantId);
  75. if (studentId && job.rawTenantId) {
  76. api_position.dislikeCompany(studentId, job.rawTenantId).catch(() => {
  77. });
  78. }
  79. common_vendor.index.showToast({ title: "已屏蔽该公司", icon: "none" });
  80. };
  81. const filterCriteria = common_vendor.ref({
  82. jobType: "",
  83. minSalary: 0,
  84. maxSalary: 50,
  85. experience: "",
  86. education: "",
  87. workCity: "",
  88. workProvince: ""
  89. });
  90. const activeFilterCount = common_vendor.computed(() => {
  91. let count = 0;
  92. if (filterCriteria.value.experience)
  93. count++;
  94. if (filterCriteria.value.education)
  95. count++;
  96. if (filterCriteria.value.minSalary > 0 || filterCriteria.value.maxSalary < 50)
  97. count++;
  98. if (filterCriteria.value.workCity)
  99. count++;
  100. return count;
  101. });
  102. const fetchJobs = (reset = false) => {
  103. if (isLoading.value)
  104. return;
  105. if (reset) {
  106. pageNum.value = 1;
  107. hasMore.value = true;
  108. jobList.value = [];
  109. }
  110. if (!hasMore.value)
  111. return;
  112. isLoading.value = true;
  113. let postTypeStr = jobTypeValue.value[currentJobType.value] || "";
  114. if (!postTypeStr && filterCriteria.value.jobType) {
  115. postTypeStr = filterCriteria.value.jobType;
  116. }
  117. const params = {
  118. pageNum: pageNum.value,
  119. pageSize: pageSize.value,
  120. postName: keyword.value.trim(),
  121. postType: postTypeStr,
  122. schoolRequirement: filterCriteria.value.education || "",
  123. gradeRequirement: filterCriteria.value.experience || "",
  124. minSalary: filterCriteria.value.minSalary,
  125. maxSalary: filterCriteria.value.maxSalary,
  126. workCity: filterCriteria.value.workCity || "",
  127. workProvince: filterCriteria.value.workProvince || ""
  128. };
  129. const currentStudentId = getStudentId();
  130. if (currentStudentId) {
  131. params.studentId = currentStudentId;
  132. }
  133. if (sortType.value === "latest") {
  134. params.orderByColumn = "createTime";
  135. params.isAsc = "desc";
  136. }
  137. api_position.getPositionList(params).then((res) => {
  138. if (res.code === 200) {
  139. const rows = res.rows || [];
  140. let formattedRows = rows.map((item) => ({
  141. id: item.id,
  142. title: item.postName,
  143. salaryText: item.salaryRange || "面议",
  144. // 使用后端翻译好的 Label 字段(如"全职"、"本科"、"3-5年"),而不是原始字典 value
  145. tags: [item.workCity, item.educationRequirementLabel || item.educationRequirement, item.gradeRequirementLabel || item.gradeRequirement].filter(Boolean),
  146. isUrgent: item.isUrgent === 1,
  147. count: item.recruitNum || 1,
  148. deadline: item.registrationEndDate ? item.registrationEndDate.split(" ")[0] : "长期有效",
  149. isExpiring: false,
  150. company: item.companyName || "平台推荐",
  151. rawTenantId: item.tenantId,
  152. // 保留原始 tenantId 用于屏蔽公司
  153. location: (item.workProvince || "") + (item.workCity ? "·" + item.workCity : ""),
  154. logo: item.companyAvatar || "/static/images/default-company.svg"
  155. }));
  156. jobList.value = reset ? formattedRows : [...jobList.value, ...formattedRows];
  157. if (jobList.value.length >= res.total || rows.length < pageSize.value) {
  158. hasMore.value = formattedRows.length >= pageSize.value;
  159. } else {
  160. pageNum.value++;
  161. }
  162. }
  163. }).finally(() => {
  164. isLoading.value = false;
  165. });
  166. };
  167. const loadMore = () => {
  168. fetchJobs(false);
  169. };
  170. const handleSearch = () => {
  171. fetchJobs(true);
  172. };
  173. const handleSearchConfirm = () => {
  174. if (keyword.value.trim()) {
  175. let history = common_vendor.index.getStorageSync("search_history");
  176. if (!history)
  177. history = [];
  178. else
  179. history = JSON.parse(history);
  180. history = history.filter((item) => item !== keyword.value.trim());
  181. history.unshift(keyword.value.trim());
  182. if (history.length > 10)
  183. history = history.slice(0, 10);
  184. common_vendor.index.setStorageSync("search_history", JSON.stringify(history));
  185. }
  186. fetchJobs(true);
  187. };
  188. common_vendor.watch([currentJobType, sortType], () => {
  189. fetchJobs(true);
  190. });
  191. const goToFilter = () => {
  192. common_vendor.index.navigateTo({
  193. url: "/pages/jobs/filter"
  194. });
  195. };
  196. const goToDetail = (item) => {
  197. common_vendor.index.navigateTo({
  198. url: "/pages/jobdetail/index?id=" + item.id
  199. });
  200. };
  201. const scrollTop = common_vendor.computed(() => {
  202. const gradientArea = titleBarMargin.value + menuButtonHeight.value + 8;
  203. const whiteArea = 82;
  204. return statusBarHeight.value + gradientArea + whiteArea;
  205. });
  206. common_vendor.onPullDownRefresh(async () => {
  207. await fetchJobs(true);
  208. common_vendor.index.stopPullDownRefresh();
  209. });
  210. common_vendor.onMounted(() => {
  211. common_vendor.index.$on("updateFilters", (params) => {
  212. filterCriteria.value = params;
  213. if (params.keyword !== void 0) {
  214. keyword.value = params.keyword;
  215. }
  216. fetchJobs(true);
  217. });
  218. loadDicts();
  219. try {
  220. const sysInfo = common_vendor.index.getSystemInfoSync();
  221. const menuInfo = common_vendor.index.getMenuButtonBoundingClientRect();
  222. if (sysInfo && menuInfo) {
  223. statusBarHeight.value = sysInfo.statusBarHeight || 20;
  224. titleBarMargin.value = menuInfo.top - sysInfo.statusBarHeight;
  225. menuButtonHeight.value = menuInfo.height;
  226. }
  227. } catch (e) {
  228. }
  229. });
  230. common_vendor.onUnmounted(() => {
  231. common_vendor.index.$off("updateFilters");
  232. });
  233. common_vendor.onPullDownRefresh(async () => {
  234. fetchJobs(true);
  235. setTimeout(() => {
  236. common_vendor.index.stopPullDownRefresh();
  237. }, 800);
  238. });
  239. return (_ctx, _cache) => {
  240. return common_vendor.e({
  241. a: common_assets._imports_0$3,
  242. b: common_vendor.o(handleSearchConfirm),
  243. c: common_vendor.o([($event) => keyword.value = $event.detail.value, handleSearch]),
  244. d: keyword.value,
  245. e: menuButtonHeight.value + "px",
  246. f: statusBarHeight.value + titleBarMargin.value + "px",
  247. g: common_vendor.f(jobTypeTabs.value, (tab, index, i0) => {
  248. return {
  249. a: common_vendor.t(tab),
  250. b: currentJobType.value === index ? 1 : "",
  251. c: index,
  252. d: common_vendor.o(($event) => currentJobType.value = index, index)
  253. };
  254. }),
  255. h: common_vendor.t(activeFilterCount.value > 0 ? "· " + activeFilterCount.value : ""),
  256. i: common_vendor.o(goToFilter),
  257. j: sortType.value === "comprehensive" ? 1 : "",
  258. k: common_vendor.o(($event) => sortType.value = "comprehensive"),
  259. l: sortType.value === "latest" ? 1 : "",
  260. m: common_vendor.o(($event) => sortType.value = "latest"),
  261. n: isLoading.value && jobList.value.length === 0
  262. }, isLoading.value && jobList.value.length === 0 ? {} : common_vendor.e({
  263. o: common_vendor.f(jobList.value, (item, index, i0) => {
  264. return common_vendor.e({
  265. a: common_vendor.t(item.title),
  266. b: item.isUrgent
  267. }, item.isUrgent ? {} : {}, {
  268. c: common_vendor.t(item.salaryText),
  269. d: common_vendor.f(item.tags, (tag, tagIdx, i1) => {
  270. return {
  271. a: common_vendor.t(tag),
  272. b: tagIdx
  273. };
  274. }),
  275. e: common_vendor.t(item.count),
  276. f: common_vendor.t(item.deadline),
  277. g: item.isExpiring
  278. }, item.isExpiring ? {} : {}, {
  279. h: item.logo,
  280. i: common_vendor.t(item.company),
  281. j: common_vendor.t(item.location),
  282. k: common_vendor.o(($event) => openFeedbackPopup(item), item.id || index),
  283. l: item.id || index,
  284. m: index === 0 ? 1 : "",
  285. n: common_vendor.o(($event) => goToDetail(item), item.id || index)
  286. });
  287. }),
  288. p: common_assets._imports_0$2,
  289. q: common_assets._imports_1$1,
  290. r: common_assets._imports_2$1,
  291. s: common_assets._imports_3$1,
  292. t: jobList.value.length === 0
  293. }, jobList.value.length === 0 ? {} : {}, {
  294. v: jobList.value.length > 0 && !hasMore.value
  295. }, jobList.value.length > 0 && !hasMore.value ? {} : {}, {
  296. w: scrollTop.value + "px",
  297. x: common_vendor.o(loadMore)
  298. }), {
  299. y: common_vendor.p({
  300. activeIndex: 0
  301. }),
  302. z: showPopup.value
  303. }, showPopup.value ? {
  304. A: common_assets._imports_3$1,
  305. B: common_vendor.o(closePopup),
  306. C: common_vendor.o(($event) => handleDislikePosition()),
  307. D: common_vendor.o(($event) => handleDislikeCompany()),
  308. E: common_vendor.o(() => {
  309. }),
  310. F: common_vendor.o(closePopup),
  311. G: common_vendor.o(() => {
  312. })
  313. } : {});
  314. };
  315. }
  316. };
  317. const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["__scopeId", "data-v-ac4b611d"]]);
  318. wx.createPage(MiniProgramPage);
  319. //# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/jobs/jobs.js.map