jobManagement.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. <template>
  2. <view class="job-management-page">
  3. <!-- 固定顶部导航栏和标签页 -->
  4. <view class="fixed-header">
  5. <!-- 自定义导航栏 -->
  6. <view class="custom-navbar">
  7. <view class="navbar-content">
  8. <view class="nav-left" @click="goBack">
  9. <u-icon name="arrow-leftward" color="#333" size="32"></u-icon>
  10. </view>
  11. <view class="nav-title">职位管理</view>
  12. <view class="nav-right"></view>
  13. </view>
  14. </view>
  15. <!-- 标签页导航 - 使用uview的u-tabs组件 -->
  16. <view class="sticky-tabs">
  17. <u-tabs
  18. :list="tabs"
  19. :current="tabIndex"
  20. @change="tabChange"
  21. :is-scroll="false"
  22. :height="88"
  23. :font-size="24"
  24. active-color="rgba(1, 107, 246, 1)"
  25. inactive-color="rgba(102, 102, 102, 1)"
  26. :bar-width="60"
  27. :bar-height="4"
  28. :gutter="0"
  29. bg-color="#ffffff"
  30. ></u-tabs>
  31. </view>
  32. </view>
  33. <!-- 职位列表 -->
  34. <view class="job-list">
  35. <!-- 有数据时显示列表 -->
  36. <scroll-view scroll-y="true" style="width: 100%;height: 70vh;" v-if="jobList.length > 0">
  37. <view
  38. class="job-card"
  39. :class="getJobStatusClass(job)"
  40. v-for="(job, index) in jobList"
  41. :key="index"
  42. @click="goNav('/my/order/pay?postPushId='+job.postPushId)"
  43. >
  44. <view class="job-card-content">
  45. <view class="job-header">
  46. <view class="job-title-section">
  47. <text class="job-title">{{job.stationName || job.title}}</text>
  48. <view class="urgent-tag" v-if="job.isUrgent">
  49. <text class="urgent-text">急聘</text>
  50. </view>
  51. </view>
  52. <view class="job-status" :class="getJobStatusClass(job)">
  53. <text class="status-text">{{job.statusName || job.status}}</text>
  54. </view>
  55. </view>
  56. <view class="job-info">
  57. <text class="job-details">{{job.city}}-{{job.county}} {{job.education}} {{job.experience}} {{job.salaryRange}} {{job.postType}}</text>
  58. </view>
  59. </view>
  60. </view>
  61. </scroll-view>
  62. <!-- 空状态显示 -->
  63. <view class="empty-state" v-else>
  64. <view class="empty-illustration">
  65. <image src="../../static/images/index/Hrempty.svg" class="empty-image" mode="aspectFit" />
  66. </view>
  67. </view>
  68. </view>
  69. <!-- 底部发布按钮 -->
  70. <view class="bottom-action">
  71. <view class="publish-btn" @click="publishNewJob">
  72. <text class="publish-text">发布新职位</text>
  73. </view>
  74. </view>
  75. </view>
  76. </template>
  77. <script>
  78. import empty from '@/components/empty.vue'
  79. export default {
  80. components: {
  81. empty
  82. },
  83. data() {
  84. return {
  85. tabIndex: 0,
  86. tabs: [
  87. { name: '全部', status: 0 },
  88. { name: '待审核', status: 1 },
  89. { name: '招聘中', status: 2 },
  90. { name: '已拒绝', status: 3 },
  91. { name: '已取消', status: 4 },
  92. { name: '已关闭', status: 5 }
  93. ],
  94. jobList: [],
  95. page: 1,
  96. limit: 10,
  97. count: 0,
  98. companyId: ''
  99. }
  100. },
  101. onLoad() {
  102. this.companyId = uni.getStorageSync('companyId');
  103. this.getJobList();
  104. // 动态设置body和html高度
  105. this.setBodyHeight();
  106. },
  107. onShow() {
  108. this.getJobList();
  109. },
  110. onReachBottom() {
  111. if (this.jobList.length < this.count) {
  112. this.page = this.page + 1;
  113. this.getJobList();
  114. }
  115. },
  116. onPullDownRefresh() {
  117. this.page = 1;
  118. this.getJobList();
  119. },
  120. methods: {
  121. goBack() {
  122. // 检查页面栈,如果没有可返回的页面,则跳转到首页
  123. const pages = getCurrentPages()
  124. if (pages.length > 1) {
  125. uni.navigateBack()
  126. } else {
  127. // 如果没有可返回的页面,跳转到首页
  128. uni.switchTab({
  129. url: '/pages/index/index'
  130. })
  131. }
  132. },
  133. // 切换菜单
  134. tabChange(e) {
  135. // u-tabs组件的change事件传递的是事件对象,需要获取index
  136. const index = typeof e === 'number' ? e : e.index
  137. this.tabIndex = index
  138. this.jobList = []; // 置空列表,显示加载进度条
  139. this.page = 1;
  140. this.getJobList();
  141. },
  142. // 获取职位列表
  143. getJobList() {
  144. let data = {
  145. status: this.tabIndex == 0 ? '' : this.tabIndex,
  146. page: this.page,
  147. limit: this.limit,
  148. companyId: this.companyId
  149. }
  150. this.$Request.getT('/app/postPush/getPostPushList', data).then(res => {
  151. if (res.code == 0) {
  152. if (this.page == 1) this.jobList = []; //如果是第一页需手动制空列表
  153. res.data.records.forEach(ret => {
  154. ret.showpeop = false
  155. if (ret.status == 1) {
  156. ret.statusName = '待审核'
  157. } else if (ret.status == 2) {
  158. ret.statusName = '招聘中'
  159. } else if (ret.status == 3) {
  160. ret.statusName = '已拒绝'
  161. } else if (ret.status == 4) {
  162. ret.statusName = '已取消'
  163. } else if (ret.status == 5) {
  164. ret.statusName = '已关闭'
  165. }
  166. this.jobList.push(ret)
  167. })
  168. this.count = res.data.total
  169. }
  170. uni.hideLoading()
  171. uni.stopPullDownRefresh()
  172. }).catch(err => {
  173. uni.hideLoading()
  174. uni.stopPullDownRefresh()
  175. })
  176. },
  177. goNav(url) {
  178. uni.navigateTo({
  179. url
  180. })
  181. },
  182. publishNewJob() {
  183. // 跳转到发布新职位页面
  184. uni.navigateTo({
  185. url: '/package/addJob/addJob'
  186. })
  187. },
  188. // 获取职位状态样式类
  189. getJobStatusClass(job) {
  190. if (job.status === 2) {
  191. return 'status-trial';
  192. } else if (job.status === 1) {
  193. return 'status-review';
  194. } else if (job.status === 3 || job.status === 4) {
  195. return 'status-failed';
  196. } else if (job.status === 5) {
  197. return 'status-closed';
  198. }
  199. return '';
  200. },
  201. setBodyHeight() {
  202. // 动态设置body和html高度为auto
  203. if (typeof document !== 'undefined') {
  204. document.body.style.height = 'auto'
  205. document.documentElement.style.height = 'auto'
  206. document.body.style.minHeight = 'auto'
  207. document.documentElement.style.minHeight = 'auto'
  208. }
  209. }
  210. }
  211. }
  212. </script>
  213. <style lang="scss" scoped>
  214. /*
  215. sticky生效条件:
  216. 1、父元素不能overflow:hidden或者overflow:auto属性。(mescroll-body设置:sticky="true"即可, mescroll-uni本身没有设置overflow)
  217. 2、必须指定top、bottom、left、right4个值之一,否则只会处于相对定位
  218. 3、父元素的高度不能低于sticky元素的高度
  219. 4、sticky元素仅在其父元素内生效,所以父元素必须是 mescroll
  220. */
  221. .sticky-tabs {
  222. z-index: 990;
  223. position: sticky;
  224. top: var(--window-top);
  225. background-color: #fff;
  226. }
  227. page {
  228. background-color: #ffffff;
  229. }
  230. .job-management-page {
  231. background-color: #ffffff;
  232. }
  233. .fixed-header {
  234. position: fixed;
  235. top: 0;
  236. left: 0;
  237. right: 0;
  238. z-index: 9999;
  239. background-color: #ffffff;
  240. }
  241. .custom-navbar {
  242. padding-top: 80rpx;
  243. background-color: #ffffff;
  244. box-sizing: border-box;
  245. .navbar-content {
  246. display: flex;
  247. align-items: center;
  248. justify-content: space-between;
  249. height: 88rpx;
  250. padding: 0 40rpx;
  251. .nav-left, .nav-right {
  252. width: 60rpx;
  253. height: 60rpx;
  254. display: flex;
  255. align-items: center;
  256. justify-content: center;
  257. }
  258. .nav-title {
  259. color: rgba(51, 51, 51, 1);
  260. font-family: DM Sans;
  261. font-size: 30rpx;
  262. font-weight: 700;
  263. line-height: 52px;
  264. letter-spacing: 0.5%;
  265. text-align: center;
  266. }
  267. }
  268. }
  269. .job-list {
  270. padding: 0 40rpx;
  271. margin-top: 280rpx;
  272. .job-card {
  273. background: #ffffff;
  274. border-radius: 12rpx;
  275. margin-bottom: 20rpx;
  276. padding: 32rpx;
  277. border: 0.5px solid rgba(227, 231, 236, 1);
  278. // box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.05);
  279. .job-card-content {
  280. .job-header {
  281. display: flex;
  282. justify-content: space-between;
  283. align-items: flex-start;
  284. margin-bottom: 16rpx;
  285. .job-title-section {
  286. display: flex;
  287. align-items: center;
  288. flex: 1;
  289. gap: 28rpx;
  290. .job-title {
  291. color: rgba(23, 23, 37, 1);
  292. font-family: DM Sans;
  293. font-size: 28rpx;
  294. font-weight: 400;
  295. line-height: 44rpx;
  296. letter-spacing: 0.5%;
  297. text-align: left;
  298. }
  299. .urgent-tag {
  300. border-radius: 8rpx;
  301. background: rgba(252, 233, 220, 1);
  302. padding: 4rpx 8rpx;
  303. .urgent-text {
  304. color: rgba(1, 107, 246, 1);
  305. font-family: DM Sans;
  306. font-size: 16rpx;
  307. font-weight: 400;
  308. // line-height: 20rpx;
  309. // letter-spacing: -0.5px;
  310. text-align: left;
  311. }
  312. }
  313. }
  314. .job-status {
  315. &.status-trial {
  316. color: rgba(1, 107, 246, 1);
  317. }
  318. &.status-review {
  319. color: rgba(1, 107, 246, 1);
  320. }
  321. &.status-failed {
  322. color: rgba(153, 153, 153, 1);
  323. .status-text {
  324. color: rgba(153, 153, 153, 1) !important;
  325. background: none !important;
  326. -webkit-background-clip: unset !important;
  327. -webkit-text-fill-color: rgba(153, 153, 153, 1) !important;
  328. background-clip: unset !important;
  329. text-fill-color: rgba(153, 153, 153, 1) !important;
  330. }
  331. }
  332. &.status-closed {
  333. color: rgba(153, 153, 153, 1);
  334. .status-text {
  335. color: rgba(153, 153, 153, 1) !important;
  336. background: none !important;
  337. -webkit-background-clip: unset !important;
  338. -webkit-text-fill-color: rgba(153, 153, 153, 1) !important;
  339. background-clip: unset !important;
  340. text-fill-color: rgba(153, 153, 153, 1) !important;
  341. }
  342. }
  343. .status-text {
  344. background: linear-gradient(132.53deg, rgba(106.94185638427734, 84.63434600830078, 214.0178680419922, 0.96),rgba(144.87640380859375, 87.8011474609375, 191.25, 1) 95%);
  345. -webkit-background-clip: text;
  346. -webkit-text-fill-color: transparent;
  347. background-clip: text;
  348. text-fill-color: transparent;
  349. font-family: DM Sans;
  350. font-size: 18rpx;
  351. font-weight: 400;
  352. line-height: 20rpx;
  353. letter-spacing: -0.5px;
  354. text-align: right;
  355. }
  356. }
  357. }
  358. .job-info {
  359. .job-details {
  360. color: rgba(120, 130, 138, 1);
  361. font-family: DM Sans;
  362. font-size: 28rpx;
  363. font-weight: 400;
  364. line-height: 36rpx;
  365. letter-spacing: 0.5%;
  366. text-align: left;
  367. }
  368. }
  369. }
  370. &.status-failed {
  371. .job-title {
  372. color: rgba(153, 153, 153, 1) !important;
  373. }
  374. .job-details {
  375. color: rgba(153, 153, 153, 1) !important;
  376. }
  377. }
  378. &.status-closed {
  379. .job-title {
  380. color: rgba(153, 153, 153, 1) !important;
  381. }
  382. .job-details {
  383. color: rgba(153, 153, 153, 1) !important;
  384. }
  385. }
  386. }
  387. }
  388. .empty-state {
  389. display: flex;
  390. // flex-direction: column;
  391. align-items: center;
  392. justify-content: center;
  393. padding: 40rpx;
  394. .empty-illustration {
  395. margin-bottom: 40rpx;
  396. .empty-image {
  397. width: 700rpx;
  398. height: 800rpx;
  399. }
  400. }
  401. .empty-text {
  402. color: rgba(120, 130, 138, 1);
  403. font-family: DM Sans;
  404. font-size: 28rpx;
  405. font-weight: 400;
  406. line-height: 36rpx;
  407. letter-spacing: 0.5%;
  408. text-align: center;
  409. }
  410. }
  411. .bottom-action {
  412. position: fixed;
  413. bottom: 0;
  414. left: 0;
  415. right: 0;
  416. padding: 30rpx 40rpx;
  417. background: #ffffff;
  418. z-index: 9999;
  419. .publish-btn {
  420. width: 100%;
  421. height: 88rpx;
  422. background: linear-gradient(90deg, rgba(13, 39, 247, 1), rgba(19, 193, 234, 1) 100%);
  423. border-radius: 44rpx;
  424. display: flex;
  425. align-items: center;
  426. justify-content: center;
  427. .publish-text {
  428. color: rgba(255, 255, 255, 1);
  429. font-family: DM Sans;
  430. font-size: 32rpx;
  431. font-weight: 400;
  432. line-height: 48rpx;
  433. letter-spacing: 0%;
  434. text-align: center;
  435. }
  436. }
  437. }
  438. </style>