mianshiDetail.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. <template>
  2. <view class="ms-detail">
  3. <view class="detail-bg"></view>
  4. <nav-bar title="面试详情"></nav-bar>
  5. <view class="detail-index">
  6. <view class="detail-title">
  7. <block v-if="info.status==2">
  8. <block v-if="currentStep === 1&&info.restHour>3">
  9. {{info.statusText}} {{info.interviewDate}}
  10. </block>
  11. <block v-else-if="currentStep === 1&&info.restHour<=3&&info.restHour>0">
  12. {{info.restHour*60}}分钟后面试
  13. </block>
  14. <block v-else-if="currentStep === 1&&info.restHour==0">
  15. 面试已开始,待签到
  16. </block>
  17. <block v-else-if="currentStep === 2">
  18. 面试已签到
  19. </block>
  20. <block v-else-if="currentStep === 3">
  21. 面试中
  22. </block>
  23. <block v-else-if="currentStep === 4">
  24. 面试已完成
  25. </block>
  26. </block>
  27. <block v-else-if="info.status==3">
  28. 面试已取消
  29. </block>
  30. </view>
  31. <view class="detail-item">
  32. <view class="user-title">
  33. <view class="user-img">
  34. <image :src="info.company&&info.company.companyLogo||'../../static/images/geren.png'" mode="aspectFill" />
  35. </view>
  36. <view class="user-name-box">
  37. <view class="user-name-com">{{info.company&&info.company.companyName||'匿名公司'}}</view>
  38. <view class="user-info-img">
  39. <image :src="info.hr&&info.hr.hrImg||'../../static/images/geren.png'" mode="aspectFill" />
  40. <view class="user-name">{{info.hrUserEntity&&info.hrUserEntity.userName||'匿名'}}·{{info.hr&&info.hr.hrPosition||'匿名职务'}}</view>
  41. </view>
  42. </view>
  43. </view>
  44. <view class="msg-box">
  45. <view class="msg-item">
  46. <view class="msg-label">面试类型</view>
  47. <view class="msg-value">{{onlineText}}</view>
  48. </view>
  49. <view class="msg-item">
  50. <view class="msg-label">时间</view>
  51. <view class="msg-value">{{info.interviewDateTime}}</view>
  52. </view>
  53. <view class="msg-item">
  54. <view class="msg-label">职位</view>
  55. <view class="msg-value">{{info.postPush&&info.postPush.ruleClassifyName}} {{info.postPush&&info.postPush.salaryRange}}</view>
  56. </view>
  57. <view class="msg-item">
  58. <view class="msg-label">联系人</view>
  59. <view class="msg-value">{{info.hrName}} {{info.hrPhone}}</view>
  60. </view>
  61. <view class="msg-item">
  62. <view class="msg-label">备注</view>
  63. <view class="msg-value">{{info.remarks}}</view>
  64. </view>
  65. <view class="msg-item" v-if="!isOnline" @tap.stop="gotoMap()">
  66. <view class="msg-label">地址</view>
  67. <view class="msg-value">{{info.address}} {{info.detailedAddress}}</view>
  68. <u-icon name="arrow-right"></u-icon>
  69. </view>
  70. <view class="msg-item" v-if="isOnline">
  71. <view class="msg-label">面试方式</view>
  72. <view class="msg-value">{{interviewTypeText}}</view>
  73. </view>
  74. <view class="msg-item" v-if="isOnline">
  75. <view class="msg-label">面试地址</view>
  76. <view class="msg-value">{{info.onlineMsg}}</view>
  77. </view>
  78. </view>
  79. <view class="map-box">
  80. <map v-if="info.lng" name="map" class="map" :longitude="parseFloat(info.lng)" :latitude="parseFloat(info.lat)" :markers="covers"></map>
  81. </view>
  82. </view>
  83. <view class="detail-item" v-if="info&&info.status==2">
  84. <view class="process-top">
  85. <view class="process-title">面试进度</view>
  86. <view hidden class="process-status">爽约说明</view>
  87. </view>
  88. <view class="process-index">
  89. <view class="interview-process">
  90. <!-- 流程步骤 -->
  91. <view class="process-steps">
  92. <!-- 步骤1: 面试时间到 -->
  93. <view
  94. class="step-item"
  95. :class="{ active: currentStep >= 1, completed: currentStep > 1 }"
  96. >
  97. <view class="step-icon">
  98. <view class="step-number">1</view>
  99. <view class="step-check" v-if="currentStep > 1">
  100. <u-icon name="checkmark" color="#fff" size="16"></u-icon>
  101. </view>
  102. </view>
  103. <view class="step-content">
  104. <view class="step-title">{{info.expired?'面试时间到':'接受面试'}}</view>
  105. <view class="step-desc">{{info.expired?'面试已开始,此时不能取消面试':'离面试开始3小时内,不可以取消面试'}}</view>
  106. </view>
  107. <view class="step-line"></view>
  108. </view>
  109. <!-- 步骤2: 面试签到 -->
  110. <view
  111. class="step-item"
  112. :class="{ active: currentStep >= 2, completed: currentStep > 2 }"
  113. >
  114. <view class="step-icon">
  115. <view class="step-number">2</view>
  116. <view class="step-check" v-if="currentStep > 2">
  117. <u-icon name="checkmark" color="#fff" size="16"></u-icon>
  118. </view>
  119. </view>
  120. <view class="step-content">
  121. <view class="step-title">面试签到</view>
  122. <view class="step-desc">到场后请及时签到,可体验面试全流程服务</view>
  123. <u-tag :text="currentStep<2?(info.expired?'签到超时':'请签到'):'已签到'" type="primary" :mode="currentStep<2&&!info.expired?'plain':'light'" size="mini"/>
  124. </view>
  125. <view class="step-line"></view>
  126. </view>
  127. <!-- 步骤3: 进行面试 -->
  128. <view
  129. class="step-item"
  130. :class="{ active: currentStep >= 3, completed: currentStep > 3 }"
  131. >
  132. <view class="step-icon">
  133. <view class="step-number">3</view>
  134. <view class="step-check" v-if="currentStep > 3">
  135. <u-icon name="checkmark" color="#fff" size="16"></u-icon>
  136. </view>
  137. </view>
  138. <view class="step-content">
  139. <view class="step-title">进行面试</view>
  140. <view class="step-desc">面试过程中,如有问题,可向客服投诉</view>
  141. </view>
  142. <view class="step-line"></view>
  143. </view>
  144. <!-- 步骤4: 面试结果 -->
  145. <view
  146. class="step-item"
  147. :class="{ active: currentStep >= 4, completed: currentStep > 4 }"
  148. >
  149. <view class="step-icon">
  150. <view class="step-number">4</view>
  151. <view class="step-check" v-if="currentStep > 4">
  152. <u-icon name="checkmark" color="#fff" size="16"></u-icon>
  153. </view>
  154. </view>
  155. <view class="step-content">
  156. <view class="step-title">面试结果</view>
  157. <view class="step-desc">面试完后30天内可向招聘方获取面试结果</view>
  158. <u-tag v-if="currentStep>=4&&info.interviewResultType==null" text="等待面试结果" type="primary" mode="plain" size="mini"/>
  159. <u-tag v-if="currentStep>=4&&info.interviewResultType!=null" :text="info.interviewResultType==0?'面试通过':(info.interviewResultType==2?'面试未通过':'结果待定')" :type="info.interviewResultType==0?'primary':'error'" mode="light" size="mini"/>
  160. <u-tag v-if="currentStep==3" text="获取面试结果" type="info" mode="light" size="mini"/>
  161. </view>
  162. <view class="step-line"></view>
  163. </view>
  164. <!-- 步骤5: 获取面试结果 -->
  165. <!-- <view
  166. class="step-item"
  167. :class="{ active: currentStep >= 5, completed: currentStep > 5 }"
  168. >
  169. <view class="step-icon">
  170. <view class="step-number">5</view>
  171. <view class="step-check" v-if="currentStep > 5">
  172. <u-icon name="checkmark" color="#fff" size="16"></u-icon>
  173. </view>
  174. </view>
  175. <view class="step-content">
  176. <view class="step-title">获取面试结果</view>
  177. <view class="step-desc"></view>
  178. </view>
  179. </view> -->
  180. </view>
  181. </view>
  182. </view>
  183. </view>
  184. <!-- 操作按钮 -->
  185. <view class="process-actions" v-if="info&&info.status==2">
  186. <button class="action-btn" v-if="currentStep === 1&&info.restHour>3" @click="updateRecord(1,3)">
  187. 取消面试
  188. </button>
  189. <button class="action-btn" v-if="currentStep === 1&&info.restHour<=3" @click="updateRecord(2,2)">
  190. 签到
  191. </button>
  192. <button
  193. class="action-btn"
  194. v-if="currentStep === 2"
  195. @click="updateRecord(3,2)"
  196. >
  197. 开始面试
  198. </button>
  199. <button
  200. class="action-btn"
  201. v-if="currentStep === 3"
  202. @click="updateRecord(4, 2)"
  203. >
  204. 面试已完成
  205. </button>
  206. <button
  207. class="action-btn"
  208. v-if="currentStep === 4"
  209. @click="handleGetResult"
  210. >
  211. 获取结果
  212. </button>
  213. <!-- <button
  214. class="action-btn complaint-btn"
  215. v-if="currentStep === 3"
  216. @click="handleComplaint"
  217. >
  218. 投诉
  219. </button> -->
  220. </view>
  221. </view>
  222. </view>
  223. </template>
  224. <script>
  225. import navBar from "@/components/nav-bar/index.vue";
  226. import { onlineInterviewType } from "@/constants/common";
  227. export default {
  228. data() {
  229. return {
  230. currentStep: 1,
  231. recordId:'',
  232. companyId:"",
  233. info:{},
  234. covers: []
  235. };
  236. },
  237. components: {
  238. navBar,
  239. },
  240. computed: {
  241. isOnline() {
  242. return this?.info?.type == 1
  243. },
  244. onlineText() {
  245. return this?.info?.type == 1 ? '线上面试' : '线下面试'
  246. },
  247. interviewTypeText() {
  248. console.log(onlineInterviewType)
  249. return onlineInterviewType[this?.info?.onlineType]?.name ?? ''
  250. }
  251. },
  252. onLoad(options){
  253. this.recordId=options&&options.recordId?options.recordId:''
  254. this.companyId=options&&options.companyId?options.companyId:''
  255. this.getData()
  256. },
  257. methods: {
  258. getData(){
  259. var that=this
  260. this.$Request.getT("/app/interviewRecord/getInterviewInfo", {companyId:this.companyId,recordId:this.recordId}).then((res) => {
  261. if (res.code == 0) {
  262. let statusArr=['','待接受','已同意','已拒绝','已过期']
  263. res.data.statusText=statusArr[res.data.status]
  264. var detailTime=res.data.detailTime?that.$queue.convert12to24(res.data.detailTime):''
  265. res.data.interviewDateTime=res.data.interviewDateTime.substring(0,10)+' '+detailTime
  266. var expired=that.$queue.isDateExpired(res.data.interviewDateTime)
  267. res.data.expired=expired[0]
  268. res.data.restHour=expired[1]
  269. res.data.interviewDate=res.data.interviewDateTime.slice(0, 10)
  270. that.info=res.data
  271. console.log(that.info)
  272. that.currentStep=!res.data.interviewProcesses||res.data.interviewProcesses==0?res.data.interviewProcesses+1:res.data.interviewProcesses
  273. that.covers.push({
  274. id:1,
  275. latitude: res.data.lat,
  276. longitude: res.data.lng,
  277. iconPath:'../../static/images/mapMarker.png',
  278. alpha:0.5,
  279. width:20,
  280. height:20,
  281. callout: {
  282. // content: res.data.detailedAddress,
  283. content: res.data.address,
  284. color: '#000', //文字颜色
  285. fontSize: 10, //文本大小
  286. padding: 5, //附近留白
  287. borderRadius: 24, //边框圆角
  288. bgColor: '#FFFFFF', //背景颜色
  289. display: 'ALWAYS', //常显
  290. }
  291. })
  292. } else {
  293. uni.showToast({
  294. title: res.msg,
  295. icon: "none",
  296. });
  297. }
  298. });
  299. },
  300. handleSignIn() {
  301. this.$emit("sign-in");
  302. uni.showToast({
  303. title: "签到成功",
  304. icon: "success",
  305. });
  306. },
  307. handleStartInterview() {
  308. this.$emit("start-interview");
  309. },
  310. handleGetResult() {
  311. if(this.info.interviewResultType==null)
  312. return this.$queue.showToast('还未出结果,请耐心等待')
  313. uni.showModal({
  314. title: "面试"+(this.info.interviewResultType==0?'已通过':(this.info.interviewResultType==2?'未通过':'结果待定')),
  315. content: this.info.interviewResultMsg||'祝您生活愉快',
  316. editable: false,
  317. showCancel:false
  318. });
  319. this.$emit("get-result");
  320. },
  321. handleComplaint() {
  322. this.$emit("complaint");
  323. uni.showModal({
  324. title: "客服投诉",
  325. content: "请描述您遇到的问题",
  326. editable: true,
  327. placeholderText: "请输入问题描述...",
  328. success: (res) => {
  329. if (res.confirm && res.content) {
  330. uni.showToast({
  331. title: "投诉已提交",
  332. icon: "success",
  333. });
  334. }
  335. },
  336. });
  337. },
  338. updateRecord(interviewProcesses,status=2){
  339. var that=this
  340. that.$Request.postJson("/app/interviewRecord/saveInterview", {
  341. recordId:that.recordId,
  342. status:status,
  343. interviewProcesses:interviewProcesses
  344. }).then(res => {
  345. if (res.code === 0) {
  346. that.info.interviewProcesses=interviewProcesses
  347. that.info.status=status
  348. that.currentStep=interviewProcesses
  349. } else {
  350. uni.showToast({
  351. title: res.msg,
  352. icon: "none"
  353. })
  354. }
  355. })
  356. },
  357. //拉起地图导航
  358. gotoMap() {
  359. let that = this
  360. uni.openLocation({
  361. latitude: that.info.lat,
  362. longitude: that.info.lng,
  363. address: that.info.address+that.info.detailedAddress,
  364. complete(ret) {
  365. }
  366. })
  367. },
  368. },
  369. };
  370. </script>
  371. <style scoped lang="scss">
  372. .ms-detail {
  373. display: flex;
  374. flex-direction: column;
  375. height: 100vh;
  376. .detail-bg {
  377. height: 744rpx;
  378. width: 100%;
  379. background: linear-gradient(180deg, rgba(255, 102, 0, 1), rgba(255, 102, 0, 0) 100%);
  380. position: absolute;
  381. left: 0;
  382. top: 0;
  383. }
  384. .detail-index {
  385. position: relative;
  386. z-index: 2;
  387. padding: 40rpx;
  388. box-sizing: border-box;
  389. flex: 1;
  390. overflow: auto;
  391. .detail-item {
  392. padding: 36rpx;
  393. box-sizing: border-box;
  394. border: 1rpx solid rgba(227, 231, 236, 1);
  395. border-radius: 6px;
  396. background: rgba(255, 255, 255, 1);
  397. margin-top: 20rpx;
  398. .process-top {
  399. display: flex;
  400. justify-content: space-between;
  401. align-items: center;
  402. .process-title {
  403. color: rgba(29, 33, 41, 1);
  404. font-family: DM Sans;
  405. font-size: 24rpx;
  406. font-weight: 500;
  407. line-height: 32rpx;
  408. }
  409. .process-status {
  410. color: #016bf6;
  411. font-family: DM Sans;
  412. font-size: 20rpx;
  413. font-weight: 700;
  414. line-height: 26rpx;
  415. }
  416. }
  417. .user-title {
  418. display: flex;
  419. align-items: center;
  420. .user-img {
  421. overflow: hidden;
  422. width: 80rpx;
  423. height: 80rpx;
  424. border-radius: 50%;
  425. margin-right: 24rpx;
  426. border: 8rpx solid #f6f6f6;
  427. image {
  428. width: 100%;
  429. height: 100%;
  430. }
  431. }
  432. .user-name-box {
  433. .user-name-com {
  434. color: #171725;
  435. font-family: DM Sans;
  436. font-size: 28rpx;
  437. font-weight: 400;
  438. line-height: 44rpx;
  439. text-align: left;
  440. }
  441. .user-info-img {
  442. display: flex;
  443. align-items: center;
  444. margin-top: 8rpx;
  445. image {
  446. width: 40rpx;
  447. height: 40rpx;
  448. border-radius: 50%;
  449. margin-right: 8rpx;
  450. }
  451. .user-name {
  452. color: #9ca4ab;
  453. font-family: DM Sans;
  454. font-size: 16rpx;
  455. font-weight: 400;
  456. line-height: 40rpx;
  457. }
  458. }
  459. }
  460. }
  461. }
  462. }
  463. .msg-box {
  464. .msg-item {
  465. display: flex;
  466. align-items: center;
  467. color: rgba(153, 153, 153, 1);
  468. font-family: DM Sans;
  469. font-size: 24rpx;
  470. font-weight: 400;
  471. line-height: 32rpx;
  472. margin-top: 12rpx;
  473. .msg-label {
  474. min-width: 120rpx;
  475. margin-right: 24rpx;
  476. }
  477. }
  478. }
  479. .detail-title {
  480. color: #fff;
  481. font-size: 50rpx;
  482. font-weight: 500;
  483. font-family: DM Sans;
  484. }
  485. }
  486. .map-box {
  487. margin-top: 24rpx;
  488. border-radius: 12rpx;
  489. overflow: hidden;
  490. .map {
  491. width: 100%;
  492. height: 154rpx;
  493. }
  494. }
  495. .interview-process {
  496. margin-top: 24rpx;
  497. }
  498. .process-header {
  499. margin-bottom: 40rpx;
  500. }
  501. .process-title {
  502. font-size: 36rpx;
  503. font-weight: bold;
  504. color: #333;
  505. }
  506. .process-steps {
  507. position: relative;
  508. }
  509. .step-item {
  510. display: flex;
  511. align-items: flex-start;
  512. margin-bottom: 50rpx;
  513. position: relative;
  514. &:last-child {
  515. margin-bottom: 0;
  516. .step-line {
  517. display: none;
  518. }
  519. }
  520. }
  521. .step-icon {
  522. width: 32rpx;
  523. height: 32rpx;
  524. border-radius: 50%;
  525. background: #f5f5f5;
  526. display: flex;
  527. align-items: center;
  528. justify-content: center;
  529. margin-right: 24rpx;
  530. position: relative;
  531. z-index: 2;
  532. flex-shrink: 0;
  533. }
  534. .step-number {
  535. font-size: 20rpx;
  536. font-weight: bold;
  537. color: #999;
  538. }
  539. .step-check {
  540. display: flex;
  541. justify-content: center;
  542. align-items: center;
  543. }
  544. .step-content {
  545. flex: 1;
  546. }
  547. .step-title {
  548. color: rgba(29, 33, 41, 1);
  549. font-family: DM Sans;
  550. font-size: 24rpx;
  551. font-weight: 600;
  552. line-height: 32rpx;
  553. margin-bottom: 8rpx;
  554. }
  555. .step-desc {
  556. color: rgba(153, 153, 153, 1);
  557. font-family: DM Sans;
  558. font-size: 20rpx;
  559. font-weight: 400;
  560. line-height: 26rpx;
  561. margin-bottom: 10rpx;
  562. }
  563. .step-line {
  564. position: absolute;
  565. left: 16rpx;
  566. top: 42rpx;
  567. bottom: -30rpx;
  568. width: 2rpx;
  569. background: #f0f0f0;
  570. z-index: 1;
  571. }
  572. /* 激活状态 */
  573. .step-item.active {
  574. .step-icon {
  575. background: #016bf6;
  576. }
  577. .step-number {
  578. color: #fff;
  579. }
  580. .step-title {
  581. color: #016bf6;
  582. font-weight: bold;
  583. }
  584. .step-line {
  585. background: #016bf6;
  586. }
  587. }
  588. /* 完成状态 */
  589. .step-item.completed {
  590. .step-icon {
  591. background: #016bf6;
  592. }
  593. .step-number {
  594. display: none;
  595. }
  596. .step-check {
  597. display: block;
  598. }
  599. }
  600. /* 操作按钮 */
  601. .process-actions {
  602. margin-top: 50rpx;
  603. display: flex;
  604. gap: 20rpx;
  605. flex-wrap: wrap;
  606. }
  607. .action-btn {
  608. flex: 1;
  609. background: #016bf6;
  610. color: #fff;
  611. border: none;
  612. border-radius: 100rpx;
  613. padding: 6rpx 24rpx;
  614. font-size: 28rpx;
  615. color: rgba(255, 255, 255, 1);
  616. font-family: DM Sans;
  617. font-size: 24rpx;
  618. font-weight: 400;
  619. text-align: center;
  620. &::after {
  621. border: none;
  622. }
  623. &:active {
  624. background: #009974;
  625. }
  626. }
  627. .complaint-btn {
  628. background: #ff4444;
  629. &:active {
  630. background: #dd3333;
  631. }
  632. }
  633. </style>