index.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. <template>
  2. <view class="talent-search-page">
  3. <!-- 搜索框 -->
  4. <view class="search flex align-center justify-center">
  5. <view class="search-box">
  6. <view class="dropdown-btn" @click="showDropdown">
  7. <text class="dropdown-text">{{ positionOptions[selectedPosition] }}</text>
  8. <u-icon name="arrow-down" color="#016BF6" size="16"></u-icon>
  9. </view>
  10. <view class="separator"></view>
  11. <input
  12. class="search-input"
  13. v-model="searchKeyword"
  14. placeholder="通过职位关键词查询"
  15. @confirm="custom"
  16. />
  17. </view>
  18. <view class="search-btn" @click="custom">搜索</view>
  19. </view>
  20. <!-- 人才列表 -->
  21. <view class="talent-list">
  22. <view
  23. class="talent-card"
  24. v-for="(talent, index) in talentList"
  25. :key="index"
  26. @click="goToTalentDetail(talent)"
  27. >
  28. <view class="talent-content">
  29. <!-- 头像和基本信息 -->
  30. <view class="talent-header">
  31. <image :src="talent.avatar" class="talent-avatar" mode="aspectFill"></image>
  32. <view class="talent-info">
  33. <view class="talent-name-section">
  34. <view class="talent-name">{{ talent.name }}</view>
  35. <view class="talent-tags">
  36. <view class="status-tag online" v-if="talent.isOnline">在线</view>
  37. <view class="status-tag hot" v-if="talent.isHot">热门搜索</view>
  38. <view class="status-tag active" v-if="talent.lastActive">{{ talent.lastActive }}</view>
  39. </view>
  40. </view>
  41. <!-- 经验和薪资 -->
  42. <view class="talent-experience">
  43. <text class="experience-text">{{ talent.experience }}</text>
  44. <text class="education-salary">{{ talent.education }} {{ talent.salary }}</text>
  45. <text class="status-text">{{ talent.jobStatus }}</text>
  46. </view>
  47. </view>
  48. </view>
  49. <!-- 当前职位 -->
  50. <view class="current-job" v-if="talent.currentJob">
  51. <image src="../../static/images/aixin.svg" class="job-icon" mode="aspectFit"></image>
  52. <text class="job-text">{{ talent.currentJob }}</text>
  53. </view>
  54. <!-- 求职期望 -->
  55. <view class="job-expectation">
  56. <image src="../../static/images/xiangzi.svg" class="job-icon" mode="aspectFit"></image>
  57. <text class="expectation-text">求职期望: {{ talent.jobExpectation }}</text>
  58. </view>
  59. <!-- 技能标签 -->
  60. <view class="skill-tags">
  61. <view
  62. class="skill-tag"
  63. v-for="(skill, skillIndex) in talent.skills"
  64. :key="skillIndex"
  65. >
  66. {{ skill }}
  67. </view>
  68. </view>
  69. <!-- 工作描述 -->
  70. <view class="job-description">
  71. <text class="description-text">{{ talent.description }}</text>
  72. </view>
  73. </view>
  74. </view>
  75. </view>
  76. <!-- 职位选择弹窗 -->
  77. <view class="position-modal" v-if="showPositionModal" @click="hidePositionModal">
  78. <view class="position-modal-content" @click.stop>
  79. <!-- 拖拽条 -->
  80. <view class="position-modal-handle"></view>
  81. <!-- 标题 -->
  82. <view class="position-modal-title">选择职位</view>
  83. <!-- 职位选项 -->
  84. <view class="position-options">
  85. <view
  86. class="position-option"
  87. :class="selectedPosition === index ? 'active' : ''"
  88. @click="selectPosition(index)"
  89. v-for="(option, index) in positionOptions"
  90. :key="index"
  91. >
  92. <view class="position-option-icon">
  93. <view class="check-icon" v-if="selectedPosition === index">✓</view>
  94. </view>
  95. <text class="position-option-text">{{ option }}</text>
  96. </view>
  97. </view>
  98. </view>
  99. </view>
  100. </view>
  101. </template>
  102. <script>
  103. export default {
  104. data() {
  105. return {
  106. searchKeyword: '',
  107. currentSx: 0,
  108. sxTypeList: [
  109. {
  110. id: 1,
  111. name: '推荐',
  112. },
  113. {
  114. id: 2,
  115. name: '最新',
  116. }
  117. ],
  118. city: '深圳',
  119. county: '',
  120. showSortModalFlag: false,
  121. selectedSort: 0,
  122. sortOptions: ['综合排序', '最新优先', '距离优先'],
  123. showPositionModal: false,
  124. selectedPosition: 0,
  125. positionOptions: ['亚马逊运营', 'TikTok运营', '采购经理', '不限职位'],
  126. talentList: [
  127. {
  128. id: 1,
  129. name: '刘**',
  130. avatar: '../../static/images/avator.png',
  131. isOnline: true,
  132. isHot: true,
  133. experience: '8年',
  134. education: '本科',
  135. salary: '10-15K',
  136. jobStatus: '在职&考虑机会',
  137. currentJob: '通拓集团·店铺运营',
  138. jobExpectation: '亚马逊运营',
  139. skills: ['精品', '铺货', 'TikTok', '平台运营', '投放策略', '3C数码'],
  140. description: '负责Amazon英国、欧洲站、制定推广与销售计划,达成团队要求的销售业绩;做好数据的统计分析工作,收集、分析...',
  141. workPeriod: '2021-2024'
  142. },
  143. {
  144. id: 2,
  145. name: '李**',
  146. avatar: '../../static/images/avator.png',
  147. lastActive: '5分钟前活跃',
  148. experience: '25年应届生',
  149. education: '本科',
  150. salary: '8-12K',
  151. jobStatus: '离职&随时到岗',
  152. currentJob: '大连海事学院·法学',
  153. jobExpectation: '亚马逊运营',
  154. skills: ['精品', '铺货', 'TikTok', '平台运营', '投放策略', '3C数码'],
  155. description: '负责Amazon英国、欧洲站、制定推广与销售计划,达成团队要求的销售业绩;做好数据的统计分析工作,收集、分析...',
  156. workPeriod: ''
  157. },
  158. {
  159. id: 3,
  160. name: '李**',
  161. avatar: '../../static/images/avator.png',
  162. lastActive: '刚刚活跃',
  163. experience: '25年应届生',
  164. education: '本科',
  165. salary: '8-12K',
  166. jobStatus: '离职&随时到岗',
  167. currentJob: '臣美科技·小红书运营',
  168. jobExpectation: '亚马逊运营',
  169. skills: ['精品', '铺货', 'TikTok', '平台运营', '投放策略', '3C数码'],
  170. description: '负责Amazon英国、欧洲站、制定推广与销售计划,达成团队要求的销售业绩;做好数据的统计分析工作,收集、分析...',
  171. workPeriod: '2021-2025'
  172. },
  173. {
  174. id: 4,
  175. name: '李**',
  176. avatar: '../../static/images/avator.png',
  177. lastActive: '刚刚活跃',
  178. experience: '25年应届生',
  179. education: '本科',
  180. salary: '8-12K',
  181. jobStatus: '离职&随时到岗',
  182. currentJob: '臣美科技·小红书运营',
  183. jobExpectation: '亚马逊运营',
  184. skills: ['精品', '铺货', 'TikTok', '平台运营', '投放策略', '3C数码'],
  185. description: '负责Amazon英国、欧洲站、制定推广与销售计划,达成团队要求的销售业绩;做好数据的统计分析工作,收集、分析...',
  186. workPeriod: ''
  187. }
  188. ]
  189. }
  190. },
  191. methods: {
  192. // 返回上一页
  193. goBack() {
  194. uni.navigateBack()
  195. },
  196. // 显示下拉菜单
  197. showDropdown() {
  198. this.showPositionModal = true
  199. },
  200. // 隐藏职位选择弹窗
  201. hidePositionModal() {
  202. this.showPositionModal = false
  203. },
  204. // 选择职位
  205. selectPosition(index) {
  206. this.selectedPosition = index
  207. // 更新下拉按钮显示的文字
  208. const selectedText = this.positionOptions[index]
  209. // 这里可以更新下拉按钮的显示文字
  210. uni.showToast({
  211. title: `已选择: ${selectedText}`,
  212. icon: 'none'
  213. })
  214. this.hidePositionModal()
  215. },
  216. // 搜索
  217. custom() {
  218. console.log('搜索关键词:', this.searchKeyword)
  219. // 这里可以添加搜索逻辑
  220. },
  221. // 清空搜索
  222. clear() {
  223. this.searchKeyword = ''
  224. },
  225. // 跳转页面
  226. goNav(url) {
  227. if (uni.getStorageSync('token')) {
  228. uni.navigateTo({
  229. url: url
  230. })
  231. } else {
  232. this.noLogin()
  233. }
  234. },
  235. // 未登录提示
  236. noLogin() {
  237. uni.showModal({
  238. title: '提示',
  239. content: '您还未登录,请先登录',
  240. confirmColor: '#00B88F',
  241. success: function(res) {
  242. if (res.confirm) {
  243. uni.navigateTo({
  244. url: '/pages/public/login'
  245. })
  246. }
  247. }
  248. })
  249. },
  250. // 显示排序弹窗
  251. showSortModal() {
  252. this.showSortModalFlag = true
  253. },
  254. // 隐藏排序弹窗
  255. hideSortModal() {
  256. this.showSortModalFlag = false
  257. },
  258. // 选择排序选项
  259. selectSort(index) {
  260. this.selectedSort = index
  261. uni.showToast({
  262. title: `已选择: ${this.sortOptions[index]}`,
  263. icon: 'none'
  264. })
  265. this.hideSortModal()
  266. },
  267. // 跳转到人才详情
  268. goToTalentDetail(talent) {
  269. console.log('查看人才详情:', talent)
  270. // 这里可以跳转到人才详情页面
  271. }
  272. }
  273. }
  274. </script>
  275. <style lang="scss" scoped>
  276. // 激活状态样式
  277. .active3 {
  278. flex-direction: row;
  279. justify-content: center;
  280. align-items: center;
  281. padding: 12rpx;
  282. border-radius: 12rpx;
  283. background: #FFFFFF !important;
  284. margin-right: 12rpx;
  285. border: 0.5px solid rgba(1, 107, 246, 1);
  286. color: rgba(1, 107, 246, 1) !important;
  287. font-family: DM Sans;
  288. font-size: 22rpx;
  289. font-weight: 400;
  290. line-height: 20rpx;
  291. letter-spacing: 0px;
  292. text-align: left;
  293. }
  294. .talent-search-page {
  295. min-height: 100vh;
  296. background-color: #f5f5f5;
  297. }
  298. // 搜索框
  299. .search {
  300. position: fixed;
  301. top: 0;
  302. width: 100%;
  303. padding: 80rpx 20rpx 20rpx 20rpx;
  304. background: linear-gradient(180.00deg, rgba(255, 102, 0, 1),rgba(255, 89, 89, 1) 83%);
  305. z-index: 99;
  306. .search-box {
  307. flex: 1;
  308. box-sizing: border-box;
  309. border: 1px solid rgba(227, 231, 236, 1);
  310. border-radius: 24px;
  311. background: rgba(241, 241, 241, 1);
  312. overflow: hidden;
  313. display: flex;
  314. align-items: center;
  315. padding: 0 32rpx;
  316. height: 60rpx;
  317. }
  318. .dropdown-btn {
  319. display: flex;
  320. align-items: center;
  321. padding: 8rpx 16rpx;
  322. background-color: #F1F1F1;
  323. border: 1rpx solid #016BF6;
  324. border-radius: 8rpx;
  325. margin-right: 12rpx;
  326. .dropdown-text {
  327. color: rgba(1, 107, 246, 1);
  328. font-family: DM Sans;
  329. font-size: 20rpx;
  330. font-weight: 400;
  331. line-height: 20rpx;
  332. letter-spacing: -0.5px;
  333. text-align: left;
  334. margin-right: 8rpx;
  335. }
  336. }
  337. .separator {
  338. width: 4rpx;
  339. height: 30rpx;
  340. background-color: rgba(153, 153, 153, 1);
  341. margin-right: 12rpx;
  342. }
  343. .search-input {
  344. flex: 1;
  345. height: 100%;
  346. background: transparent;
  347. color: #333;
  348. font-family: DM Sans;
  349. font-size: 20rpx;
  350. font-weight: 400;
  351. line-height: 48rpx;
  352. letter-spacing: 0.5%;
  353. text-align: left;
  354. &::placeholder {
  355. color: rgba(182, 182, 182, 1);
  356. font-family: DM Sans;
  357. font-size: 20rpx;
  358. font-weight: 400;
  359. line-height: 48rpx;
  360. letter-spacing: 0.5%;
  361. text-align: left;
  362. }
  363. }
  364. .search-btn {
  365. width: 80rpx;
  366. color: rgba(255, 255, 255, 1);
  367. font-family: DM Sans;
  368. font-size: 20rpx;
  369. font-weight: 500;
  370. line-height: 48rpx;
  371. letter-spacing: 0.5%;
  372. text-align: center;
  373. }
  374. }
  375. .search-bar {
  376. display: flex;
  377. align-items: center;
  378. margin-bottom: 20rpx;
  379. .search-input {
  380. flex: 1;
  381. height: 80rpx;
  382. background-color: #f8f8f8;
  383. border-radius: 40rpx;
  384. padding: 0 30rpx;
  385. font-size: 28rpx;
  386. color: #333;
  387. margin-right: 20rpx;
  388. }
  389. .search-btn {
  390. width: 120rpx;
  391. height: 80rpx;
  392. background-color: #016BF6;
  393. color: #ffffff;
  394. border-radius: 40rpx;
  395. display: flex;
  396. align-items: center;
  397. justify-content: center;
  398. font-size: 28rpx;
  399. }
  400. }
  401. .filter-tags {
  402. display: flex;
  403. flex-wrap: wrap;
  404. gap: 16rpx;
  405. .filter-tag {
  406. padding: 12rpx 24rpx;
  407. background-color: #ffffff;
  408. border: 1rpx solid #e5e5e5;
  409. border-radius: 20rpx;
  410. font-size: 24rpx;
  411. color: #666;
  412. }
  413. }
  414. .talent-list {
  415. margin-top: 160rpx;
  416. padding: 20rpx;
  417. }
  418. .talent-card {
  419. background-color: #ffffff;
  420. border-radius: 16rpx;
  421. margin-bottom: 20rpx;
  422. padding: 30rpx;
  423. box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
  424. }
  425. .talent-content {
  426. .talent-header {
  427. display: flex;
  428. align-items: flex-start;
  429. .talent-avatar {
  430. width: 80rpx;
  431. height: 80rpx;
  432. border-radius: 50%;
  433. margin-right: 20rpx;
  434. }
  435. .talent-info {
  436. flex: 1;
  437. .talent-name-section {
  438. display: flex;
  439. align-items: center;
  440. justify-content: flex-start;
  441. width: 100%;
  442. margin-bottom: 6rpx;
  443. }
  444. .talent-name {
  445. color: rgba(51, 51, 51, 1);
  446. font-family: DM Sans;
  447. font-size: 28rpx;
  448. font-weight: 500;
  449. line-height: 36rx;
  450. letter-spacing: 0.5%;
  451. text-align: left;
  452. margin-right: 16rpx;
  453. }
  454. .talent-tags {
  455. display: flex;
  456. flex-wrap: wrap;
  457. gap: 10rpx;
  458. .status-tag {
  459. padding: 8rpx;
  460. border-radius: 12rpx;
  461. font-size: 18rpx;
  462. font-family: DM Sans;
  463. font-weight: 400;
  464. line-height: 20rpx;
  465. letter-spacing: -0.5px;
  466. text-align: left;
  467. &.online {
  468. background: rgba(213, 255, 231, 1);
  469. color: rgba(29, 209, 104, 1);
  470. }
  471. &.hot {
  472. background: rgba(252, 233, 220, 1);
  473. color: rgba(1, 107, 246, 1);
  474. }
  475. &.active {
  476. color: rgba(153, 153, 153, 1);
  477. }
  478. }
  479. }
  480. }
  481. }
  482. .talent-experience {
  483. display: flex;
  484. align-items: center;
  485. margin-bottom: 12rpx;
  486. gap: 16rpx;
  487. color: rgba(156, 164, 171, 1);
  488. font-family: DM Sans;
  489. font-size: 24rpx;
  490. font-weight: 400;
  491. line-height: 32rpx;
  492. letter-spacing: 0.5%;
  493. text-align: left;
  494. }
  495. .current-job {
  496. display: flex;
  497. align-items: center;
  498. margin-bottom: 12rpx;
  499. .job-icon {
  500. width: 40rpx;
  501. height: 40rpx;
  502. margin-right: 8rpx;
  503. }
  504. .job-text {
  505. color: rgba(156, 164, 171, 1);
  506. font-family: DM Sans;
  507. font-size: 24rpx;
  508. font-weight: 400;
  509. line-height: 40rpx;
  510. letter-spacing: 0.5%;
  511. text-align: left;
  512. }
  513. }
  514. .job-expectation {
  515. display: flex;
  516. align-items: center;
  517. margin-bottom: 16rpx;
  518. .job-icon {
  519. width: 40rpx;
  520. height: 40rpx;
  521. margin-right: 8rpx;
  522. }
  523. .expectation-text {
  524. color: rgba(156, 164, 171, 1);
  525. font-family: DM Sans;
  526. font-size: 24rpx;
  527. font-weight: 400;
  528. line-height: 40rpx;
  529. letter-spacing: 0.5%;
  530. text-align: left;
  531. }
  532. }
  533. .skill-tags {
  534. display: flex;
  535. flex-wrap: wrap;
  536. gap: 10rpx;
  537. margin-bottom: 16rpx;
  538. .skill-tag {
  539. padding: 8rpx;
  540. background: rgba(198, 198, 198, 0.1);
  541. border-radius: 12rpx;
  542. color: rgba(153, 153, 153, 1);
  543. font-family: DM Sans;
  544. font-size: 20rpx;
  545. font-weight: 400;
  546. line-height: 20rpx;
  547. letter-spacing: -0.5px;
  548. text-align: left;
  549. }
  550. }
  551. .job-description {
  552. margin-bottom: 12rpx;
  553. .description-text {
  554. color: rgba(97, 110, 124, 1);
  555. font-family: DM Sans;
  556. font-size: 24rpx;
  557. font-weight: 400;
  558. line-height: 32rpx;
  559. letter-spacing: 0px;
  560. text-align: left;
  561. }
  562. }
  563. .work-period {
  564. text-align: right;
  565. .period-text {
  566. font-size: 22rpx;
  567. color: #999;
  568. }
  569. }
  570. }
  571. // 职位选择弹窗样式
  572. .position-modal {
  573. position: fixed;
  574. top: 0;
  575. left: 0;
  576. right: 0;
  577. bottom: 0;
  578. background: rgba(0, 0, 0, 0.5);
  579. z-index: 10001;
  580. display: flex;
  581. align-items: flex-end;
  582. .position-modal-content {
  583. width: 100%;
  584. background: #ffffff;
  585. border-radius: 24rpx 24rpx 0 0;
  586. padding: 20rpx 40rpx 40rpx 40rpx;
  587. max-height: 60vh;
  588. .position-modal-handle {
  589. width: 80rpx;
  590. height: 8rpx;
  591. background: #E5E5E5;
  592. border-radius: 4rpx;
  593. margin: 0 auto 30rpx auto;
  594. }
  595. .position-modal-title {
  596. font-size: 32rpx;
  597. font-weight: 600;
  598. color: #333333;
  599. text-align: center;
  600. padding-bottom: 30rpx;
  601. margin-bottom: 30rpx;
  602. border-bottom: 1px solid rgba(153, 153, 153, 0.25);
  603. }
  604. .position-options {
  605. .position-option {
  606. display: flex;
  607. align-items: center;
  608. padding: 24rpx 32rpx;
  609. margin-bottom: 16rpx;
  610. border-radius: 42rpx;
  611. border: 2rpx solid rgba(227, 231, 236, 1);
  612. &.active {
  613. background: #F0F8FF;
  614. border-color: #007AFF;
  615. .position-option-icon {
  616. background: #007AFF;
  617. border-color: #007AFF;
  618. .check-icon {
  619. color: #ffffff;
  620. }
  621. }
  622. .position-option-text {
  623. color: #007AFF;
  624. font-weight: 500;
  625. }
  626. }
  627. .position-option-icon {
  628. width: 40rpx;
  629. height: 40rpx;
  630. border-radius: 50%;
  631. border: 2rpx solid #E5E5E5;
  632. background: #ffffff;
  633. display: flex;
  634. align-items: center;
  635. justify-content: center;
  636. margin-right: 24rpx;
  637. .check-icon {
  638. font-size: 24rpx;
  639. color: #ffffff;
  640. font-weight: bold;
  641. }
  642. }
  643. .position-option-text {
  644. font-size: 28rpx;
  645. color: #333333;
  646. flex: 1;
  647. }
  648. }
  649. }
  650. }
  651. }
  652. </style>