resume-card.vue 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. <template>
  2. <view class="resume-card">
  3. <view class="top-section flex justify-between">
  4. <view class="flex user-info">
  5. <view class="avatar-container">
  6. <image :src="avatar ? avatar : '/static/images/logo.jpg'" class="avatar"></image>
  7. <image src="@/static/images/svg/male.svg" class="sex-icon" v-if="sex == 1"></image>
  8. <image src="@/static/images/svg/female.svg" class="sex-icon" v-else-if="sex == 2"></image>
  9. </view>
  10. <view class="user-info-box">
  11. <view class="flex">
  12. <text class="name">{{ userName }}</text>
  13. <view class="online-status" :class="{ online: lineValue == ONLINE, offline: lineValue == OFFLINE }">{{ lineText }}</view>
  14. </view>
  15. <view class="base-info flex align-center">
  16. <text v-for="(item, index) in baseInfoArr" :key="index">{{ item }}</text>
  17. </view>
  18. </view>
  19. </view>
  20. <view class="salary">{{ salaryRange }}</view>
  21. </view>
  22. <view class="flex align-center justify-between company-info">
  23. <view class="flex align-center">
  24. <image src="@/static/images/svg/bag.svg" class="icon"></image>
  25. <text class="text">{{ companyName }} · {{ positionName }}</text>
  26. <view class="company-tag" v-if="isCrossCompany">跨境</view>
  27. </view>
  28. <view class="time">{{ companyTime }}</view>
  29. </view>
  30. <view class="tags">
  31. <view class="tag" v-for="(item, index) in skills" :key="index">{{ item }}</view>
  32. </view>
  33. <view class="bottom-section flex align-center">
  34. <image src="@/static/images/svg/heart.svg" class="expection-icon"></image>
  35. 求职期望:{{ ruleClassifyName }}
  36. </view>
  37. </view>
  38. </template>
  39. <script>
  40. const ONLINE = 'ONLINE'
  41. const OFFLINE = 'OFFLINE'
  42. export default {
  43. data() {
  44. return {
  45. avatar: '',
  46. sex: 0, // 1男、2女
  47. userName: '',
  48. baseInfoArr: [], // 基本信息
  49. companyName: '', // 公司
  50. positionName: '', // 职位
  51. salaryRange: '', // 薪资范围
  52. lineValue: '', // 在线状态
  53. isCrossCompany: false, // 是否是跨境
  54. companyTime: '', // 当前公司工作时间
  55. ruleClassifyName: '', // 期望岗位
  56. skills: [], // 技能标签
  57. };
  58. },
  59. computed: {
  60. lineText() {
  61. if (this.lineValue === ONLINE) {
  62. return '在线'
  63. } else if (this.lineValue === OFFLINE) {
  64. return '离线'
  65. }
  66. return ''
  67. }
  68. },
  69. mounted() {
  70. this.getData()
  71. },
  72. methods: {
  73. // 获取数据
  74. getData() {
  75. this.$Request
  76. .getT('/app/resumes/getResumesReviewData')
  77. .then(res => {
  78. if (res.code === 0) {
  79. const data = res.data
  80. this.avatar = data.userAvatar
  81. this.sex = data.userSex
  82. this.userName = data.userName
  83. this.lineValue = data.onlineStatus
  84. // 设置薪资
  85. this.salaryRange = this.setSalaryRange(data.salaryRange)
  86. // 设置年龄、工龄、学历
  87. if (data.userAge) {
  88. this.baseInfoArr.push(`${data.userAge}岁`)
  89. }
  90. if (data.resumesWorkExperience) {
  91. this.baseInfoArr.push(data.resumesWorkExperience)
  92. }
  93. if (data.degree) {
  94. this.baseInfoArr.push(data.degree)
  95. }
  96. this.companyName = data.companyName
  97. this.positionName = data.position
  98. this.ruleClassifyName = data.ruleClassifyName
  99. // this.skills
  100. }
  101. console.log(res)
  102. })
  103. },
  104. setSalaryRange(value) {
  105. if (value && value.indexOf('-')) {
  106. const salaryValue = value.split('-')
  107. return `${formatNumberToK(salaryValue[0])}-${formatNumberToK(salaryValue[1])}`
  108. }
  109. return ''
  110. },
  111. formatNumberToK(numStr) {
  112. // 1. 异常处理:空值、非字符串、非数字字符串直接返回原内容
  113. if (typeof numStr !== 'string' || numStr.trim() === '') {
  114. return numStr || '';
  115. }
  116. // 2. 将字符串转为数字(自动忽略首尾空格)
  117. const num = Number(numStr.trim());
  118. // 3. 非有效数字的情况,返回原字符串(如"abc"、"12a3")
  119. if (isNaN(num)) {
  120. return numStr;
  121. }
  122. // 4. 小于1000的数字,直接返回原数字的字符串(无格式变化)
  123. if (num < 1000) {
  124. return String(Math.floor(num)); // 确保无小数(比如"999.9"转"999")
  125. }
  126. // 5. 大于等于1000的数字,除以1000取整后拼接K
  127. const kNum = Math.floor(num / 1000);
  128. return `${kNum}K`;
  129. }
  130. }
  131. }
  132. </script>
  133. <style lang="scss" scoped>
  134. .resume-card {
  135. background: #fff;
  136. border-radius: 12rpx;
  137. padding: 16rpx 36rpx;
  138. .top-section {
  139. margin-bottom: 12rpx;
  140. .avatar-container {
  141. position: relative;
  142. margin-right: 20rpx;
  143. .avatar {
  144. width: 72rpx;
  145. height: 72rpx;
  146. border-radius: 72rpx;
  147. border: 1px solid rgba(240, 240, 240, 1);
  148. }
  149. .sex-icon {
  150. position: absolute;
  151. top: 0;
  152. right: 0;
  153. width: 22rpx;
  154. height: 22rpx;
  155. background: #fff;
  156. border-radius: 22rpx;
  157. }
  158. }
  159. .user-info-box {
  160. .name {
  161. font-size: 28rpx;
  162. font-weight: 500;
  163. line-height: 36rpx;
  164. color: rgba(51, 51, 51, 1);
  165. margin-right: 20rpx;
  166. }
  167. .online-status {
  168. font-size: 16rpx;
  169. line-height: 20rpx;
  170. padding: 8rpx 20rpx;
  171. border-radius: 8rpx;
  172. }
  173. .online {
  174. color: rgba(29, 209, 104, 1);
  175. background: rgba(213, 255, 231, 1);
  176. }
  177. .offline {
  178. color: #999;
  179. background: #ddd;
  180. }
  181. // .other {
  182. // color: #8858C5;
  183. // background: #ECE1FD;
  184. // }
  185. .base-info {
  186. margin-top: 6rpx;
  187. text {
  188. font-size: 24rpx;
  189. line-height: 32rpx;
  190. color: rgba(1, 107, 246, 1);
  191. margin-right: 12rpx;
  192. }
  193. }
  194. }
  195. .salary {
  196. font-size: 24rpx;
  197. font-weight: 700;
  198. line-height: 40rpx;
  199. background-image: linear-gradient(90.00deg, rgba(13, 39, 247, 1),rgba(19, 193, 234, 1));
  200. -webkit-background-clip: text;
  201. color: transparent;
  202. background-clip: text;
  203. }
  204. }
  205. .company-info {
  206. .icon {
  207. width: 40rpx;
  208. height: 40rpx;
  209. margin-right: 8rpx;
  210. }
  211. .text {
  212. max-width: 420rpx;
  213. color: rgba(156, 164, 171, 1);
  214. font-size: 24rpx;
  215. line-height: 40rpx;
  216. }
  217. .company-tag {
  218. height: 32rpx;
  219. font-size: 20rpx;
  220. line-height: 1;
  221. color: #fff;
  222. border-radius: 8rpx;
  223. background: linear-gradient(90.00deg, rgba(13, 39, 247, 0.75) 0%,rgba(19, 193, 234, 0.75) 100%);
  224. padding: 6rpx 7rpx;
  225. margin-left: 20rpx;
  226. box-sizing: border-box;
  227. }
  228. .time {
  229. font-size: 20rpx;
  230. line-height: 40rpx;
  231. color: rgba(144.88, 87.8, 191.25, 1);
  232. }
  233. }
  234. // tag样式
  235. .tags {
  236. display: flex;
  237. flex-wrap: wrap;
  238. .tag {
  239. padding: 8rpx;
  240. border-radius: 8rpx;
  241. background: rgba(198, 198, 198, 0.1);
  242. font-size: 20rpx;
  243. line-height: 1;
  244. color: rgba(153, 153, 153, 1);
  245. margin-top: 8rpx;
  246. margin-right: 8rpx;
  247. }
  248. }
  249. .bottom-section {
  250. color: rgba(156, 164, 171, 1);
  251. font-size: 24rpx;
  252. line-height: 40rpx;
  253. margin-top: 12rpx;
  254. .expection-icon {
  255. width: 40rpx;
  256. height: 40rpx;
  257. margin-right: 8rpx;
  258. }
  259. }
  260. }
  261. </style>