123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861 |
- <template>
- <view class="page">
- <!-- Custom Navbar -->
- <view class="custom-navbar">
- <view class="navbar-content">
- <view class="navbar-left" @click="goBack">
- <u-icon name="arrow-leftward" color="color: rgba(51, 51, 51, 1);" size="36"></u-icon>
- </view>
- <view class="navbar-title">沟通记录</view>
- <view class="navbar-right"></view>
- </view>
- </view>
- <view class="tab-section-bg">
- <text class="title-text">沟通记录</text>
- <text class="interview-manage" @click="goToInterviewManage">面试管理</text>
- </view>
- <!-- Tab Navigation -->
- <view class="tab-section">
- <u-tabs
- :list="tabs"
- :current="activeTab"
- @change="switchTab"
- :is-scroll="false"
- :height="88"
- :font-size="24"
- active-color="rgba(1, 107, 246, 1)"
- inactive-color="rgba(102, 102, 102, 1)"
- :bar-width="80"
- :bar-height="4"
- :gutter="40"
- bg-color="#ffffff"
- :bar-style="{
- borderRadius: '2rpx'
- }"
- ></u-tabs>
- </view>
- <!-- Content Section -->
- <view class="content-section">
- <!-- Communication Records List -->
- <view class="communication-list" v-if="activeTab === 0">
- <!-- 有数据时显示列表 -->
- <view v-if="communicationRecords.length > 0">
- <!-- Date Group -->
- <view class="date-group" v-for="(group, groupIndex) in groupedRecords" :key="groupIndex">
- <view class="date-header">
- <text class="date-text">{{ group.date }}</text>
- </view>
-
- <!-- Records for this date -->
- <view
- class="talent-card"
- v-for="(record, recordIndex) in group.records"
- :key="recordIndex"
- @click="goToResumeDetail(record)"
- >
- <view class="talent-content">
- <!-- 头像和基本信息 -->
- <view class="talent-header">
- <image :src="record.avatar" class="talent-avatar" mode="aspectFill"></image>
- <view class="talent-info">
- <view class="talent-name-section">
- <view class="talent-name">{{ record.name }}</view>
- <view class="talent-tags">
- <view class="status-tag online" v-if="record.isOnline">在线</view>
- <view class="status-tag hot" v-if="record.isHot">热门搜索</view>
- <view class="status-tag active" v-if="record.lastActive">{{ record.lastActive }}</view>
- </view>
- </view>
- <!-- 经验和薪资 -->
- <view class="talent-experience">
- <text class="experience-text">{{ record.experience }}</text>
- <text class="education-salary">{{ record.education }} {{ record.salary }}</text>
- <text class="status-text">{{ record.jobStatus }}</text>
- </view>
- </view>
- </view>
-
- <!-- 当前职位 -->
- <view class="current-job" v-if="record.currentJob">
- <image src="../../static/images/aixin.svg" class="job-icon" mode="aspectFit"></image>
- <text class="job-text">{{ record.currentJob }}</text>
- <text class="work-period">{{ record.workPeriod }}</text>
- </view>
-
- <!-- 求职期望 -->
- <view class="job-expectation">
- <image src="../../static/images/xiangzi.svg" class="job-icon" mode="aspectFit"></image>
- <text class="expectation-text">求职期望: {{ record.jobExpectation }}</text>
- </view>
-
- <!-- 技能标签 -->
- <view class="skill-tags">
- <view
- class="skill-tag"
- v-for="(skill, skillIndex) in record.skills"
- :key="skillIndex"
- >
- {{ skill }}
- </view>
- </view>
-
- <!-- 工作描述 -->
- <view class="job-description">
- <text class="description-text">{{ record.description }}</text>
- </view>
- </view>
- </view>
- </view>
- </view>
-
- <!-- 空状态显示 -->
- <view class="empty-state" v-else>
- <view class="empty-illustration">
- <image src="../../static/images/index/Hrempty.svg" class="empty-image" mode="aspectFit" />
- </view>
- </view>
- </view>
- <!-- Interview Records List -->
- <view class="interview-list" v-if="activeTab === 1">
- <!-- Date Selector -->
- <view class="date-selector">
- <view class="week-days">
- <text class="day-name" v-for="day in currentWeekDays" :key="day.name">{{ day.name }}</text>
- </view>
- <view class="week-dates">
- <view
- class="date-item"
- :class="{ active: date.isSelected }"
- v-for="date in currentWeekDates"
- :key="date.value"
- @click="selectDate(date)"
- >
- <text class="date-value">{{ date.value }}</text>
- </view>
- </view>
- </view>
- <!-- Interview Records -->
- <view class="interview-records">
- <!-- 有数据时显示列表 -->
- <view v-if="interviewRecords.length > 0">
- <view
- class="interview-record"
- :class="{ 'today': record.isToday, 'tomorrow': record.isTomorrow }"
- v-for="(record, index) in interviewRecords"
- :key="index"
- @click="goToInterviewDetail(record)"
- >
- <view class="record-content">
- <view class="record-left">
- <text class="date-label">{{ record.dateLabel }}</text>
- <text class="time-label">{{ record.time }}</text>
- </view>
- <view class="record-divider"></view>
- <view class="record-right">
- <text class="candidate-name">{{ record.candidateName }}</text>
- <text class="candidate-details">{{ record.experience }} {{ record.education }} {{ record.salary }}</text>
- </view>
- </view>
- </view>
- </view>
-
- <!-- 空状态显示 -->
- <view class="empty-state" v-else>
- <view class="empty-illustration">
- <image src="../../static/images/index/Hrempty.svg" class="empty-image" mode="aspectFit" />
- </view>
- </view>
- </view>
- </view>
- <!-- 收藏标签页 -->
- <view class="favorite-list" v-if="activeTab === 2">
- <!-- 有数据时显示列表 -->
- <view v-if="favoriteRecords.length > 0">
- <!-- 收藏记录列表内容 -->
- </view>
-
- <!-- 空状态显示 -->
- <view class="empty-state" v-else>
- <view class="empty-illustration">
- <image src="../../static/images/index/Hrempty.svg" class="empty-image" mode="aspectFit" />
- </view>
- </view>
- </view>
- <!-- 收藏职位标签页 -->
- <view class="favorite-jobs-list" v-if="activeTab === 3">
- <!-- 有数据时显示列表 -->
- <view v-if="favoriteJobs.length > 0">
- <!-- 收藏职位列表内容 -->
- </view>
-
- <!-- 空状态显示 -->
- <view class="empty-state" v-else>
- <view class="empty-illustration">
- <image src="../../static/images/index/Hrempty.svg" class="empty-image" mode="aspectFit" />
- </view>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script>
- export default {
- data() {
- return {
- statusBarHeight: 0,
- activeTab: 0,
- tabs: [
- { name: '沟通过' },
- { name: '面试' },
- { name: '收藏' },
- { name: '收藏职位' }
- ],
- communicationRecords: [
- {
- id: 1,
- name: '刘先生',
- avatar: '../../static/images/avator.png',
- isOnline: true,
- isHot: true,
- experience: '8年',
- education: '本科',
- salary: '10-15K',
- jobStatus: '在职&考虑机会',
- currentJob: '通拓集团·店铺运营',
- jobExpectation: '亚马逊运营',
- skills: ['精品', '铺货', 'TikTok', '平台运营', '投放策略', '3C数码'],
- description: '负责Amazon英国、欧洲站、制定推广与销售计划,达成团队要求的销售业绩;做好数据的统计分析工作,收集、分析...',
- workPeriod: '1年10个月',
- date: '07-24'
- },
- {
- id: 2,
- name: '刘先生',
- avatar: '../../static/images/avator.png',
- isOnline: true,
- isHot: true,
- experience: '8年',
- education: '本科',
- salary: '10-15K',
- jobStatus: '在职&考虑机会',
- currentJob: '通拓集团·店铺运营',
- jobExpectation: '亚马逊运营',
- skills: ['精品', '铺货', 'TikTok', '平台运营', '投放策略', '3C数码'],
- description: '负责Amazon英国、欧洲站、制定推广与销售计划,达成团队要求的销售业绩;做好数据的统计分析工作,收集、分析...',
- workPeriod: '1年10个月',
- date: '07-25'
- }
- ],
- // 面试相关数据
- selectedDate: null, // 当前选中的日期
- // 收藏相关数据
- favoriteRecords: [], // 收藏记录(空数组,显示空状态)
- favoriteJobs: [], // 收藏职位(空数组,显示空状态)
- interviewRecords: [
- {
- dateLabel: '今天',
- time: '20:40',
- candidateName: '刘先生',
- experience: '8年',
- education: '本科',
- salary: '10-15K',
- isToday: true,
- isTomorrow: false
- },
- {
- dateLabel: '明天',
- time: '20:40',
- candidateName: '刘先生',
- experience: '8年',
- education: '本科',
- salary: '10-15K',
- isToday: false,
- isTomorrow: true
- },
- {
- dateLabel: '8月15日',
- time: '20:40',
- candidateName: '刘先生',
- experience: '8年',
- education: '本科',
- salary: '10-15K',
- isToday: false,
- isTomorrow: false
- }
- ]
- }
- },
- computed: {
- groupedRecords() {
- const groups = {}
- this.communicationRecords.forEach(record => {
- if (!groups[record.date]) {
- groups[record.date] = {
- date: record.date,
- records: []
- }
- }
- groups[record.date].records.push(record)
- })
- return Object.values(groups)
- },
- // 当前周的星期名称
- currentWeekDays() {
- const weekDays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
- return weekDays.map(name => ({ name }))
- },
- // 当前周的日期
- currentWeekDates() {
- const today = new Date()
- const currentDay = today.getDay() // 0-6,0是周日
-
- // 获取本周一的日期(周一开始)
- const monday = new Date(today)
- // 如果今天是周日(0),则往前推6天到周一
- // 如果今天是周一(1),则往前推0天
- // 如果今天是周二(2),则往前推1天
- const daysToMonday = currentDay === 0 ? 6 : currentDay - 1
- monday.setDate(today.getDate() - daysToMonday)
-
- // 生成本周7天的日期
- const weekDates = []
- for (let i = 0; i < 7; i++) {
- const date = new Date(monday)
- date.setDate(monday.getDate() + i)
-
- const isToday = date.toDateString() === today.toDateString()
- const isSelected = this.selectedDate ?
- date.toDateString() === this.selectedDate.toDateString() : isToday
-
- weekDates.push({
- value: date.getDate().toString(),
- date: date,
- isSelected: isSelected
- })
- }
-
- return weekDates
- }
- },
- onLoad() {
- const systemInfo = uni.getSystemInfoSync()
- this.statusBarHeight = systemInfo.statusBarHeight || 0
- },
- methods: {
- goBack() {
- uni.navigateBack()
- },
- switchTab(index) {
- this.activeTab = index
- },
- goToResumeDetail(record) {
- console.log('查看简历详情:', record)
- uni.navigateTo({
- url: `/pages/talentSearch/resumeDetail?resumeId=${record.id}`
- })
- },
- selectDate(date) {
- // 选中当前点击的日期
- this.selectedDate = date.date
- console.log('选中日期:', date.date)
- },
- goToInterviewDetail(record) {
- console.log('查看面试详情:', record)
- // uni.navigateTo({
- // url: `/pages/interview/detail?id=${record.id}`
- // })
- },
- goToInterviewManage() {
- console.log('跳转到面试管理')
- uni.navigateTo({
- url: '/pages/recruitmentData/interviewManage'
- })
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .page {
- height: 100vh;
- overflow: hidden;
- }
- .tab-section-bg {
- position: fixed;
- top: 150rpx;
- left: 0;
- right: 0;
- z-index: 1000;
- background-color: #ffffff;
- padding: 32rpx;
- display: flex;
- justify-content: space-between;
- align-items: center;
-
- .title-text {
- color: rgba(51, 51, 51, 1);
- font-family: DM Sans;
- font-size: 48rpx;
- font-weight: 700;
- line-height: 60rpx;
- letter-spacing: 0px;
- }
-
- .interview-manage {
- color: rgba(1, 107, 246, 1);
- font-family: DM Sans;
- font-size: 28rpx;
- font-weight: 400;
- line-height: 60rpx;
- letter-spacing: 0px;
- text-align: left;
- }
- }
- /* Custom Navbar */
- .custom-navbar {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- z-index: 1000;
- background-color: #ffffff;
- padding-top: 80rpx;
- }
- .navbar-content {
- display: flex;
- align-items: center;
- justify-content: space-between;
- height: 44px;
- padding: 20rpx;
- }
- .navbar-left {
- width: 44px;
- height: 44px;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .navbar-title {
- color: rgba(51, 51, 51, 1);
- font-family: DM Sans;
- font-size: 30rpx;
- font-weight: 700;
- line-height: 52rpx;
- letter-spacing: 0.5%;
- text-align: center;
- }
- .navbar-right {
- width: 44px;
- }
- /* Tab Section */
- .tab-section {
- position: fixed;
- top: 250rpx;
- left: 0;
- right: 0;
- background: white;
- z-index: 99;
- }
- /* Content Section */
- .content-section {
- margin-top: 330rpx;
- padding: 20rpx;
- height: calc(100vh - 330rpx) !important;
- overflow-y: auto;
- }
- /* Date Group */
- .date-group {
- margin-bottom: 20rpx;
- }
- .date-header {
- margin-bottom: 16rpx;
- }
- .date-text {
- color: rgba(153, 153, 153, 1);
- font-family: DM Sans;
- font-size: 24rpx;
- font-weight: 400;
- line-height: 32rpx;
- margin-left: 32rpx;
- }
- /* Talent Card */
- .talent-card {
- background-color: #ffffff;
- border-radius: 16rpx;
- margin-bottom: 20rpx;
- padding: 30rpx;
- // box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
- }
- .talent-content {
- .talent-header {
- display: flex;
- align-items: flex-start;
-
- .talent-avatar {
- width: 80rpx;
- height: 80rpx;
- border-radius: 50%;
- margin-right: 20rpx;
- }
-
- .talent-info {
- flex: 1;
-
- .talent-name-section {
- display: flex;
- align-items: center;
- justify-content: flex-start;
- width: 100%;
- margin-bottom: 6rpx;
- }
-
- .talent-name {
- color: rgba(51, 51, 51, 1);
- font-family: DM Sans;
- font-size: 28rpx;
- font-weight: 500;
- line-height: 36rpx;
- letter-spacing: 0.5%;
- text-align: left;
- margin-right: 16rpx;
- }
-
- .talent-tags {
- display: flex;
- flex-wrap: wrap;
- gap: 10rpx;
-
- .status-tag {
- padding: 8rpx;
- border-radius: 12rpx;
- font-size: 18rpx;
- font-family: DM Sans;
- font-weight: 400;
- line-height: 20rpx;
- letter-spacing: -0.5px;
- text-align: left;
-
- &.online {
- background: rgba(213, 255, 231, 1);
- color: rgba(29, 209, 104, 1);
- }
-
- &.hot {
- background: rgba(252, 233, 220, 1);
- color: rgba(1, 107, 246, 1);
- }
-
- &.active {
- color: rgba(153, 153, 153, 1);
- }
- }
- }
- }
- }
-
- .talent-experience {
- display: flex;
- align-items: center;
- margin-bottom: 12rpx;
- gap: 16rpx;
- color: rgba(156, 164, 171, 1);
- font-family: DM Sans;
- font-size: 24rpx;
- font-weight: 400;
- line-height: 32rpx;
- letter-spacing: 0.5%;
- text-align: left;
- }
-
- .current-job {
- display: flex;
- align-items: center;
- margin-bottom: 12rpx;
-
- .job-icon {
- width: 40rpx;
- height: 40rpx;
- margin-right: 8rpx;
- }
-
- .job-text {
- color: rgba(156, 164, 171, 1);
- font-family: DM Sans;
- font-size: 24rpx;
- font-weight: 400;
- line-height: 40rpx;
- letter-spacing: 0.5%;
- text-align: left;
- flex: 1;
- }
-
- .work-period {
- color: rgba(153, 153, 153, 1);
- font-family: DM Sans;
- font-size: 22rpx;
- font-weight: 400;
- line-height: 28rpx;
- }
- }
-
- .job-expectation {
- display: flex;
- align-items: center;
- margin-bottom: 16rpx;
- .job-icon {
- width: 40rpx;
- height: 40rpx;
- margin-right: 8rpx;
- }
-
- .expectation-text {
- color: rgba(156, 164, 171, 1);
- font-family: DM Sans;
- font-size: 24rpx;
- font-weight: 400;
- line-height: 40rpx;
- letter-spacing: 0.5%;
- text-align: left;
- }
- }
-
- .skill-tags {
- display: flex;
- flex-wrap: wrap;
- gap: 10rpx;
- margin-bottom: 16rpx;
-
- .skill-tag {
- padding: 8rpx;
- background: rgba(198, 198, 198, 0.1);
- border-radius: 12rpx;
- color: rgba(153, 153, 153, 1);
- font-family: DM Sans;
- font-size: 20rpx;
- font-weight: 400;
- line-height: 20rpx;
- letter-spacing: -0.5px;
- text-align: left;
- }
- }
-
- .job-description {
- margin-bottom: 12rpx;
-
- .description-text {
- color: rgba(97, 110, 124, 1);
- font-family: DM Sans;
- font-size: 24rpx;
- font-weight: 400;
- line-height: 32rpx;
- letter-spacing: 0px;
- text-align: left;
- }
- }
- }
- /* Interview List Styles */
- .interview-list {
- padding: 0 20rpx;
- }
- /* Date Selector */
- .date-selector {
- background: #ffffff;
- border-radius: 12rpx;
- padding: 24rpx 0;
- // margin-bottom: 20rpx;
- // border: 0.5px solid rgba(227, 231, 236, 1);
- }
- .week-days {
- display: flex;
- justify-content: space-between;
- margin-bottom: 16rpx;
- }
- .day-name {
- color: rgba(153, 153, 153, 1);
- font-family: DM Sans;
- font-size: 24rpx;
- font-weight: 400;
- line-height: 32rpx;
- text-align: center;
- flex: 1;
- }
- .week-dates {
- display: flex;
- justify-content: space-between;
- }
- .date-item {
- flex: 1;
- display: flex;
- justify-content: center;
- align-items: center;
- height: 60rpx;
- border-radius: 50%;
- cursor: pointer;
- min-width: 60rpx;
- max-width: 60rpx;
- }
- .date-item.active {
- background: rgba(1, 107, 246, 1);
- }
- .date-value {
- color: rgba(51, 51, 51, 1);
- font-family: DM Sans;
- font-size: 28rpx;
- font-weight: 400;
- line-height: 36rpx;
- text-align: center;
- }
- .date-item.active .date-value {
- color: #ffffff;
- }
- /* Interview Records */
- .interview-records {
- background: #ffffff;
- border-radius: 12rpx;
- padding: 24rpx 0;
- // border: 0.5px solid rgba(227, 231, 236, 1);
- }
- .interview-record {
- display: flex;
- position: relative;
- border-radius: 8rpx;
- margin-bottom: 16rpx;
- }
- .interview-record.today {
- background: rgba(250, 187, 143, 1);
- }
- .interview-record:not(.today) {
- background: rgba(221, 221, 221, 1);
- }
- .interview-record:last-child {
- margin-bottom: 0;
- }
- /* Record Content */
- .record-content {
- flex: 1;
- display: flex;
- align-items: center;
- gap: 24rpx;
- }
- .record-left {
- display: flex;
- flex-direction: column;
- min-width: 80rpx;
- padding: 32rpx;
- }
- .record-divider {
- width: 10rpx;
- height: 100%;
- background: rgba(1, 107, 246, 1);
- }
- .record-right {
- flex: 1;
- display: flex;
- flex-direction: column;
- gap: 8rpx;
- }
- .date-label {
- color: rgba(106, 106, 106, 1);
- font-family: DM Sans;
- font-size: 16rpx;
- font-weight: 400;
- line-height: 40rpx;
- letter-spacing: 0.5%;
- text-align: right;
- }
- .time-label {
- color: rgba(106, 106, 106, 1);
- font-family: DM Sans;
- font-size: 24rpx;
- font-weight: 400;
- line-height: 32rpx;
- letter-spacing: 0.5%;
- text-align: left;
- }
- .candidate-name {
- color: rgba(51, 51, 51, 1);
- font-family: DM Sans;
- font-size: 32rpx;
- font-weight: 600;
- line-height: 40rpx;
- }
- .candidate-details {
- color: rgba(102, 102, 102, 1);
- font-family: DM Sans;
- font-size: 24rpx;
- font-weight: 400;
- line-height: 32rpx;
- }
- /* Empty State - 与jobManagement页面保持一致 */
- .empty-state {
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 40rpx;
-
- .empty-illustration {
- margin-bottom: 40rpx;
-
- .empty-image {
- width: 700rpx;
- height: 800rpx;
- }
- }
-
- .empty-text {
- color: rgba(120, 130, 138, 1);
- font-family: DM Sans;
- font-size: 28rpx;
- font-weight: 400;
- line-height: 36rpx;
- letter-spacing: 0.5%;
- text-align: center;
- }
- }
- </style>
|