screen.vue 12 KB

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