screen.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. <template>
  2. <view class="flex flex-direction" style="height: 100vh;">
  3. <navBar title="筛选" color="#000" />
  4. <!-- 列表 -->
  5. <view class="list flex justify-between">
  6. <scroll-view scroll-y="true" @scroll="scrolls" scroll-with-animation="true"
  7. :scroll-into-view="'bottomView' + current" style="width: 100%; height: 100%;">
  8. <block v-if="type">
  9. <view class="list-r-item" :id="'bottomView' + index" v-if="list.length > 0 && index != 3"
  10. v-for="(item, index) in list" :key="index">
  11. <view class="list-r-item-title">
  12. {{ item.name }}
  13. </view>
  14. <view class="list-r-item-childs flex justify-around align-center flex-wrap">
  15. <view class="list-r-item-childs-i flex justify-center align-center"
  16. v-for="(ite, ind) in item.list" :class="ite.select == true ? 'activeRight' : ''"
  17. @click="selectHyList(index, item.name, ite, ind)" :key="ind">
  18. {{ ite.value }}
  19. </view>
  20. <view class="list-r-item-childs-i flex justify-center align-center"
  21. style="height: 0; padding: 0">
  22. </view>
  23. </view>
  24. </view>
  25. </block>
  26. <block v-else>
  27. <view class="list-r-item" :id="'bottomView' + index" v-if="list.length > 0"
  28. v-for="(item, index) in list" :key="index">
  29. <view class="list-r-item-title">
  30. {{ item.name }}
  31. </view>
  32. <view class="list-r-item-childs flex justify-around align-center flex-wrap">
  33. <view class="list-r-item-childs-i flex justify-center align-center"
  34. v-for="(ite, ind) in item.list" :class="ite.select == true ? 'activeRight' : ''"
  35. @click="selectHyList(index, item.name, ite, ind)" :key="ind">
  36. {{ ite.value }}
  37. </view>
  38. <view class="list-r-item-childs-i flex justify-center align-center"
  39. style="height: 0; padding: 0">
  40. </view>
  41. </view>
  42. </view>
  43. </block>
  44. <empty v-if="list.length == 0" />
  45. </scroll-view>
  46. </view>
  47. <!-- 底部按钮 -->
  48. <view class="bottom flex justify-center">
  49. <view class="bottom-box flex justify-between">
  50. <view @click="cleanSe()" class="bottom-box-left flex justify-center align-center">
  51. 清除
  52. </view>
  53. <view @click="submitSe()" class="bottom-box-right flex justify-center align-center">
  54. 确定
  55. </view>
  56. </view>
  57. </view>
  58. </view>
  59. </template>
  60. <script>
  61. import empty from "../../components/empty.vue";
  62. import navBar from "@/components/nav-bar/index.vue";
  63. export default {
  64. components: {
  65. empty,
  66. navBar
  67. },
  68. data() {
  69. return {
  70. current: 0,
  71. currents: 0,
  72. list: [],
  73. top_list: [],
  74. selectArr: [],
  75. type: "",
  76. isBrowse: false, //是否是从用户浏览记录里过来的
  77. isCompyBrowse: false, //是否是从企业浏览记录过来的
  78. isCompyHistory: false, //是否是从企业的投递记录过来的
  79. };
  80. },
  81. onLoad(option) {
  82. if (option.type) {
  83. this.type = option.type;
  84. }
  85. if (option.isBrowse) {
  86. this.isBrowse = true;
  87. } else {
  88. this.isBrowse = false;
  89. }
  90. if (option.isCompyBrowse) {
  91. this.isCompyBrowse = true;
  92. } else {
  93. this.isCompyBrowse = false;
  94. }
  95. if (option.isCompyHistory) {
  96. this.isCompyHistory = true;
  97. } else {
  98. this.isCompyHistory = false;
  99. }
  100. this.getSchools();
  101. },
  102. methods: {
  103. /**
  104. * 清空筛选条件并清空缓存
  105. */
  106. cleanSe() {
  107. this.list.map((item) => {
  108. item.list.map((ite) => {
  109. ite.select = false;
  110. });
  111. });
  112. if (this.isBrowse) {
  113. uni.removeStorageSync("browse");
  114. } else if (this.isCompyBrowse) {
  115. uni.removeStorageSync("isCompyBrowse");
  116. } else if (this.isCompyHistory) {
  117. uni.removeStorageSync("isCompyHistory");
  118. } else {
  119. uni.removeStorageSync("filter");
  120. }
  121. },
  122. /**
  123. * 处理选中的条件
  124. */
  125. submitSe() {
  126. let arr = JSON.parse(JSON.stringify(this.list));
  127. arr =
  128. arr &&
  129. arr.map((item) => {
  130. item.list =
  131. item.list &&
  132. item.list.filter((val) => {
  133. if (val.select) return val;
  134. });
  135. if (item.list.length > 0) {
  136. return item;
  137. }
  138. });
  139. arr = arr.filter((val) => {
  140. if (val) return val;
  141. });
  142. if (this.isBrowse) {
  143. uni.setStorageSync("browse", arr);
  144. } else if (this.isCompyBrowse) {
  145. uni.setStorageSync("isCompyBrowse", arr);
  146. } else if (this.isCompyHistory) {
  147. uni.setStorageSync("isCompyHistory", arr);
  148. } else {
  149. uni.setStorageSync("filter", arr);
  150. }
  151. uni.$emit('updateScreenFilterRecord')
  152. uni.navigateBack();
  153. },
  154. /**
  155. * @param {Object} index 外层下标
  156. * @param {Object} name 外层名称
  157. * @param {Object} info 内层对象
  158. * @param {Object} ind 内层下标
  159. * 选择右侧的筛选
  160. * 学历、薪资、经验单选,其余可以多选
  161. */
  162. selectHyList(index, name, info, ind) {
  163. // 定义需要单选的类型
  164. const singleSelectTypes = ['学历要求', '薪资范围(单选)', '经验要求'];
  165. if (singleSelectTypes.includes(name)) {
  166. // 单选逻辑:先取消当前分类下所有选项的选中状态,再选中当前点击的选项
  167. this.list[index].list.forEach(item => {
  168. item.select = false;
  169. });
  170. info.select = true;
  171. } else {
  172. // 其余多选逻辑保持不变
  173. if (info.value == "不限") {
  174. this.list[index].list.forEach(item => {
  175. item.select = false;
  176. });
  177. info.select = true;
  178. } else {
  179. this.list[index].list.forEach(item => {
  180. if (item.value == "不限") {
  181. item.select = false;
  182. }
  183. });
  184. info.select = !info.select;
  185. }
  186. }
  187. this.$forceUpdate();
  188. },
  189. /**
  190. * @param {Object} index
  191. * 点击切换分类
  192. */
  193. change_click_index(index) {
  194. this.current = index;
  195. //解决最后一个 ***来回*** 问题
  196. uni.setStorageSync("resolve", "last");
  197. setTimeout(() => {
  198. uni.removeStorageSync("resolve");
  199. }, 400);
  200. },
  201. scrolls(e) {
  202. if (!uni.getStorageSync("resolve")) {
  203. // this.get_node_details(e);
  204. }
  205. },
  206. /**
  207. * @param {Object} options
  208. * 获取节点信息
  209. */
  210. get_node_details(options) {
  211. const query = uni.createSelectorQuery().in(this);
  212. query
  213. .selectAll(".list-r-item")
  214. .boundingClientRect((data) => {
  215. this.top_list = data.map((item) => {
  216. return Math.ceil(item.top);
  217. });
  218. this.async_detail_msg(options);
  219. })
  220. .exec();
  221. },
  222. /**
  223. * @param {Object} options
  224. * 设置滚动的位置
  225. */
  226. async_detail_msg(options) {
  227. let top_page = options.detail.scrollTop + this.top_list[0];
  228. for (let i = 0; i < this.top_list.length; i++) {
  229. let node1 = this.top_list[i];
  230. let node2 = this.top_list[i + 1];
  231. if (node2 && top_page >= node1 && top_page < node2) {
  232. this.current = i;
  233. break;
  234. } else if (node2 && top_page === node2) {
  235. this.current = i + 1;
  236. break;
  237. }
  238. }
  239. },
  240. /**
  241. * 获取学历列表
  242. */
  243. getSchools() {
  244. this.$Request
  245. .get("/app/dict/list", {
  246. type: "学历",
  247. })
  248. .then((res) => {
  249. if (res.code == 0) {
  250. let list = [{
  251. value: "不限",
  252. }, ];
  253. let obj = {
  254. name: "学历要求",
  255. list: [...list, ...res.data],
  256. };
  257. this.getMoney(obj);
  258. }
  259. });
  260. },
  261. /**
  262. * 获取薪资 列表
  263. */
  264. getMoney(obj1) {
  265. this.$Request
  266. .get("/app/dict/list", {
  267. type: "薪资 ",
  268. })
  269. .then((res) => {
  270. if (res.code == 0) {
  271. let list = [{
  272. value: "不限",
  273. }, ];
  274. let obj = {
  275. name: "薪资范围(单选)",
  276. list: [...list, ...res.data],
  277. };
  278. this.getJy(obj1, obj);
  279. }
  280. });
  281. },
  282. /**
  283. * 获取工作经验列表
  284. */
  285. getJy(obj1, obj2) {
  286. this.$Request
  287. .get("/app/dict/list", {
  288. type: "工作经验 ",
  289. })
  290. .then((res) => {
  291. if (res.code == 0) {
  292. let list = [{
  293. value: "不限",
  294. }, ];
  295. let obj = {
  296. name: "经验要求",
  297. list: [...list, ...res.data],
  298. };
  299. this.getGm(obj1, obj2, obj);
  300. }
  301. });
  302. },
  303. /**
  304. * 获取公司规模列表
  305. */
  306. getGm(obj1, obj2, obj3) {
  307. this.$Request
  308. .get("/app/dict/list", {
  309. type: "公司规模 ",
  310. })
  311. .then((res) => {
  312. if (res.code == 0) {
  313. let list = [{
  314. value: "不限",
  315. }, ];
  316. let obj = {
  317. name: "公司规模",
  318. list: [...list, ...res.data],
  319. };
  320. this.getIndustryList(obj1, obj2, obj3, obj);
  321. }
  322. });
  323. },
  324. /**
  325. * 获取行业列表
  326. */
  327. getIndustryList(obj1, obj2, obj3, obj4) {
  328. this.$Request.get("/app/industry/getIndustryList").then((res) => {
  329. if (res.code == 0) {
  330. let list = [{
  331. value: "不限",
  332. }, ];
  333. let arrAy = [];
  334. res.data.map((item) => {
  335. arrAy = [...arrAy, ...item.childrenList];
  336. });
  337. let arrs = JSON.parse(JSON.stringify(arrAy).replace(/industryName/g, "value"));
  338. let obj = {
  339. name: "行业",
  340. list: [...list, ...arrs],
  341. };
  342. let arr = [];
  343. arr[0] = obj1;
  344. arr[1] = obj2;
  345. arr[2] = obj3;
  346. arr[3] = obj4;
  347. //arr[4] = obj;
  348. arr.map((item) => {
  349. item.list.map((ite) => {
  350. ite.select = false;
  351. });
  352. });
  353. this.list = arr;
  354. // 从缓存加载选中状态
  355. const storageKeys = [{
  356. key: 'filter',
  357. condition: !this.isBrowse && !this.isCompyBrowse && !this.isCompyHistory
  358. },
  359. {
  360. key: 'browse',
  361. condition: this.isBrowse
  362. },
  363. {
  364. key: 'isCompyBrowse',
  365. condition: this.isCompyBrowse
  366. },
  367. {
  368. key: 'isCompyHistory',
  369. condition: this.isCompyHistory
  370. }
  371. ];
  372. for (const {
  373. key,
  374. condition
  375. }
  376. of storageKeys) {
  377. if (condition && uni.getStorageSync(key)) {
  378. const storedData = uni.getStorageSync(key);
  379. const selectedValues = [];
  380. storedData.forEach(item => {
  381. item.list.forEach(ite => {
  382. selectedValues.push(ite.value);
  383. });
  384. });
  385. this.list.forEach(item => {
  386. item.list.forEach(ite => {
  387. if (selectedValues.includes(ite.value)) {
  388. ite.select = true;
  389. }
  390. });
  391. });
  392. break;
  393. }
  394. }
  395. }
  396. });
  397. },
  398. },
  399. };
  400. </script>
  401. <style lang="scss">
  402. /* 样式保持不变 */
  403. page {
  404. background-color: #ffffff;
  405. }
  406. .activeRight {
  407. color: rgba(1, 107, 246, 1) !important;
  408. background-color: rgba(153, 196, 250, 0.4) !important;
  409. border-radius: 18rpx !important;
  410. border: 0.5px solid rgba(1, 107, 246, 1);
  411. }
  412. .active {
  413. border-left: 8rpx solid #016bf6 !important;
  414. color: #016bf6 !important;
  415. }
  416. .list {
  417. width: 100%;
  418. flex: 1;
  419. overflow: hidden;
  420. .list-l {
  421. width: 30%;
  422. height: 100%;
  423. .list-l-item {
  424. margin-top: 40rpx;
  425. font-size: 28rpx;
  426. color: #121212;
  427. padding-left: 20rpx;
  428. border-left: 8rpx solid #ffffff;
  429. }
  430. }
  431. .list-r-item {
  432. width: 100%;
  433. margin-top: 40rpx;
  434. .list-r-item-title {
  435. width: 100%;
  436. color: #121212;
  437. font-size: 32rpx;
  438. font-weight: bold;
  439. padding-left: 30rpx;
  440. }
  441. .list-r-item-childs {
  442. width: 100%;
  443. .list-r-item-childs-i {
  444. width: calc((100% - 120rpx) / 2);
  445. margin-top: 20rpx;
  446. padding-top: 16rpx;
  447. padding-bottom: 16rpx;
  448. padding-left: 16rpx;
  449. padding-right: 16rpx;
  450. font-size: 26rpx;
  451. color: #121212;
  452. background: rgba(245, 248, 254, 1);
  453. text-align: center;
  454. border-radius: 18rpx;
  455. }
  456. }
  457. }
  458. }
  459. .bottom {
  460. width: 100%;
  461. background-color: #ffffff;
  462. .bottom-box {
  463. width: 686rpx;
  464. height: 80rpx;
  465. margin: 20rpx 0 40rpx;
  466. .bottom-box-left {
  467. width: 40%;
  468. height: 80rpx;
  469. color: #ffffff;
  470. border-radius: 999rpx;
  471. background: rgba(153, 196, 250, 1);
  472. }
  473. .bottom-box-right {
  474. width: 57%;
  475. height: 80rpx;
  476. border-radius: 999rpx;
  477. background: var(--线性渐变,
  478. linear-gradient(90deg, rgba(13, 39, 247, 1), rgba(19, 193, 234, 1) 100%));
  479. color: #ffffff;
  480. }
  481. }
  482. }
  483. </style>