<template> <view class="report_detail" :style="vuex_theme"> <view class="box form_info"> <view class="info"> <view class="avatar">{{getNameLastTwo(detail.studentName)}}</view> <view class="name">{{overflowHide(detail.studentName, 6)}}</view> <view class="number">NO.{{detail.studentNumber}}</view> </view> <view class="company"> <text>联系电话</text> <text>{{detail.studentPhone || '--'}}</text> </view> <view class="company"> <text>班级信息</text> <text>{{detail.departmentName}} {{detail.classInfo}}</text> </view> </view> <view class="tab_box"> <view class="tab"> <u-tabs :list="tabs" :scrollable="false" lineWidth="30rpx" lineHeight="4rpx" lineColor="var(--primary-color)" :inactiveStyle="{fontSize:'28rpx', color:'#4A4A53'}" :activeStyle="{fontSize:'36rpx', color:'var(--primary-color)'}" @change="handelTab" :current="current"> </u-tabs> </view> <view class="u-icon" v-if="current == 0"> <u-icon slot="icon" size="40" :name="'/static/img/home/selectIcon.png'" @click="show = true"></u-icon> </view> </view> <view v-if="current == 0"> <view class="box attendance"> <view class="title">考勤</view> <view class="item_icon"> <text>考勤天数</text> <view @click="handelRecord('signin')"> <text>{{detail.attendanceCount || 0}}天</text> <u-icon :style="{margin:'0 0 0 8rpx'}" name="arrow-right" color="#909097" size="28"></u-icon> </view> </view> </view> <view class="box attendance"> <view class="title">提交材料</view> <view class="item_icon"> <text>三方协议</text> <view @click="handelRecord('aggrent')"> <text>查看</text> <u-icon :style="{margin:'0 0 0 8rpx'}" name="arrow-right" color="#909097" size="28"></u-icon> </view> </view> <view class="item_icon"> <text>日志</text> <view @click="handelRecord('daily')"> <text>{{detail.dailyLogCount || 0}}篇</text> <u-icon :style="{margin:'0 0 0 8rpx'}" name="arrow-right" color="#909097" size="28"></u-icon> </view> </view> <view class="item_icon"> <text>周志</text> <view @click="handelRecord('weekly')"> <text>{{detail.weekLogCount || 0}}篇</text> <u-icon :style="{margin:'0 0 0 8rpx'}" name="arrow-right" color="#909097" size="28"></u-icon> </view> </view> <view class="item_icon"> <text>月志</text> <view @click="handelRecord('monthly')"> <text>{{detail.monthlyLogCount || 0}}篇</text> <u-icon :style="{margin:'0 0 0 8rpx'}" name="arrow-right" color="#909097" size="28"></u-icon> </view> </view> <view class="item_icon"> <text>实习报告</text> <view @click="handelRecord('report')"> <text>{{detail.internshipReportCount || 0}}次</text> <u-icon :style="{margin:'0 0 0 8rpx'}" name="arrow-right" color="#909097" size="28"></u-icon> </view> </view> </view> </view> <view class="practical_courses" v-if="current == 1"> <view class="list_box" v-if="list.length > 0"> <view class="item" v-for="(item, i) in list" :key="i"> <view class="company_box"> <view class="company"> <u-icon size="32rpx" :name="vuex_baseImgUrl && `${vuex_baseImgUrl}internshipUnitIcon.png`"></u-icon> <text>{{item.companyName}}</text> </view> <view class="address"> <u-icon size="32rpx" :name="vuex_baseImgUrl && `${vuex_baseImgUrl}addressIcon.png`" ></u-icon> <text>{{item.province}}/{{item.city}}/{{item.district}}</text> </view> </view> <view class="projiect_item" v-for="(ele, index) in item.jobResultList" :key="index"> <view class="projiect"> <text>实习岗位</text> <text>{{ele.jobName || '--'}}</text> </view> <view class="projiect"> <text>实习时间</text> <text>{{ ele.startTime>0 ? `${timeFormat(ele.startTime)}至${timeFormat(ele.endTime)}` : '--'}}</text> </view> <view class="projiect"> <text>联系人</text> <text>{{ele.contactName|| '--'}}</text> </view> <view class="projiect"> <text>联系电话</text> <text>{{ele.contactPhone|| ''}}</text> </view> </view> </view> <c-loading :loading="loading"></c-loading> </view> </view> <view class="practical_courses" v-if="current == 2"> <view class="list_box" v-if="list.length > 0"> <view class="item" v-for="(item, i) in list" :key="i"> <view class="title_box"> <view class="title">{{item.courseName}}</view> <text class="credit">学分:{{item.credit}}分</text> </view> <view class="projiect_item" v-for="(ele, index) in item.entryDataList" :key="index" @click="projiectSel(ele)"> <view class="projiect"> <text>计划名称</text> <text>{{ele.planName || '--'}}</text> </view> <view class="projiect"> <text>实习时间</text> <text>{{ ele.internshipStartTime>0 ? `${timeFormat(ele.internshipStartTime)}至${timeFormat(ele.internshipEndTime)}` : '--'}}</text> </view> <view class="projiect"> <text>实习形式</text> <!-- <text @click="handelDetail(ele, 'internship')" :style="{color:'var(--primary-color)',textDecoration:'underline'}">{{ele.formNumber|| '--'}}</text> --> <text>{{ele.practiceForm=='oneself'?'自主实习':'集中实习'}}</text> </view> <view class="projiect"> <text>总成绩</text> <text>{{ele.totalScore|| '--'}}</text> </view> <!-- <view class="projiect" v-if="ele.credit"> <text>学分</text> <text @click="handelDetail(ele, 'credit')" :style="{color:'var(--primary-color)'}">{{ele.credit}}</text> </view> --> <!-- <view class="projiect" v-else> <text>学分</text> <text>{{'--'}}</text> </view> --> </view> </view> <c-loading :loading="loading"></c-loading> </view> </view> <u-popup :show="show" mode="bottom" @close="close" :round="22"> <view class="popup"> <view style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 28px;"> <view class="title"> 计划筛选 </view> <image class="close" src="/static/img/home/closepop.png" @click="close" mode=""></image> </view> <view class="search"> <u-search placeholder="请输入计划关键词搜索" placeholderColor="#C1C1C9" searchIconSize="36" height="64rpx" bgColor="#F4F4F4" :showAction="true" shape="round" v-model="sxsearch" @custom="workSearch()" @search="workSearch()"> </u-search> </view> <scroll-view v-if="works.length>0" scroll-y="true" style="height: 80%; margin-top: 40rpx;" @scrolltolower="lower()"> <view class="item_box" v-for="(item,index) in works" :key="index" @click="popupSelItem(item)"> <view style="display: flex; align-items: center; justify-content: space-between;"> <view class="item_title"> {{item.name}} </view> <image v-if="item.id == planId" style="width: 20px; height: 20px;" :src="vuex_baseImgUrl && `${vuex_baseImgUrl}popselect.png`" mode=""></image> </view> </view> </scroll-view> <view v-else class="no_data" @click="jumpVerified"> <view class="text_black_28"> 暂未搜索到该计划 </view> </view> </view> </u-popup> <!-- <u-popup :show="show" mode="right" @close="close" @open="open" :closeOnClickOverlay="false"> <view class="popup_search"> <view class="content"> <view class="title">按计划筛选</view> <scroll-view class="scroll" scroll-y="true"> <view class="item" v-for="(item, i) in projectList" :key="i" @click="handelClick(item)"> <view class="selectItem" v-if="item.id == planId"> <text>{{item.name}}</text> </view> <view v-else> <text>{{item.name}}</text> </view> </view> </scroll-view> </view> <view class="footer"> <view class="left_btn"> <c-button type="cancel" text="重置" @click="handelCancel"> </c-button> </view> <view class="right_btn"> <c-button type="confirm" text="确定" @click="hancelSubmit"> </c-button> </view> </view> </view> </u-popup> --> </view> </template> <script> import { mapGetters, mapState, mapActions } from 'vuex' import listMixin from "@/common/mixins/list-mixin.js"; import { getInternshipProcessDetailApi, getInternshipJobListApi, getPracticalCoursesListApi, getPlanListApi, } from '@/config/api.js'; export default { data() { return { studentId: '', detail: {}, current: 0, tabs: [{ name: '实习过程', }, { name: '实习岗位', }, { name: '实践课程' }], show: false, planId: '', list: [], search: { //搜索对象必须为key search的对象 status: 'wait,pass,reject', }, works: [], workspage: 1, workstotal: 0, sxsearch: "", } }, onLoad(option) { // this.$store.dispatch(`home/getProjectList`, { // pageSize: -1, // }) this.worksloadData() this.studentId = option.studentId; getInternshipProcessDetailApi({ studentId: option.studentId, }).then(data => { if (data) { this.detail = data } }) }, computed: { ...mapState('home', { // 箭头函数可使代码更简练 projectList: 'projectList', }), }, methods: { projiectSel(e) { this.$u.route({ url: `pages/main/internship/traineeInterList/traineeInterList?&id=${e.entryId}` }) }, getNameLastTwo(value) { if (value && value.length > 3) { return value.substring(value.length - 3) } else { return value; } }, overflowHide(value, num = 4) { if (value && value.length > num) { return `${value.slice(0, num)}...` } else { return value; } }, timeFormat(timestamp, format = 'yyyy-mm-dd') { return timestamp > 0 ? uni.$u.timeFormat(timestamp, format) : '--' }, handelTab(item) { this.current = item.index; switch (item.index) { case 1: this.finished = false; this.loading = "loadmore"; this.page = 0; this.list = []; this._getList(); break; case 2: this.finished = false; this.loading = "loadmore"; this.page = 0; this.list = []; this._getList(); break; } }, handelRecord(type) { switch (type) { case 'signin': if(!this.planId) { this.$u.toast('请先选择实习计划'); return; } this.$u.route({ url: `pages/main/internship/signInList/signInList?studentId=${this.detail.studentId}&planId=${this.planId}` }) break; case 'aggrent': this.$u.route({ url: `pages/main/internship/agreementList/agreementList?studentId=${this.detail.studentId}&planId=${this.planId}` }) break; case 'daily': this.$u.route({ url: `pages/main/internship/studentLogReview/studentLogReview?category=daily&studentId=${this.detail.studentId}&planId=${this.planId}` }) break; case 'weekly': this.$u.route({ url: `pages/main/internship/studentLogReview/studentLogReview?category=weekly&studentId=${this.detail.studentId}&planId=${this.planId}` }) break; case 'monthly': this.$u.route({ url: `pages/main/internship/studentLogReview/studentLogReview?category=monthly&studentId=${this.detail.studentId}&planId=${this.planId}` }) break; case 'report': this.$u.route({ url: `pages/main/home/reportReview/reportReview?studentId=${this.detail.studentId}&planId=${this.planId}` }) break; } }, open() { }, close() { this.show = false }, handelClick(values) { this.planId = values.id; }, handelCancel() { this.switchValue = false; this.planId = ''; }, hancelSubmit() { this.finished = false; getInternshipProcessDetailApi({ studentId: this.studentId, planId: this.planId, }).then(data => { if (data) { this.detail = data; this.show = false } }) }, // scroll-view到底部加载更多 onreachBottom() {}, // 搜索 searchSubmit() { // 调用混合搜索 this._searchData(); }, // 模拟后端分页 async getData(requestParams) { const { search = {} } = requestParams; let params = {}; params.pageNumber = requestParams.page + 1; params.pageSize = 5; if (this.studentId) { params.studentId = this.studentId } if (this.current == 1) { return await getInternshipJobListApi(params); } else { return await getPracticalCoursesListApi(params); } }, // 数据请求(没错就是这么少的代码) async _getList() { if (this.page == 0) { this.list = []; } // 根据实际情况修改自己修改key let result = await this.getData({ page: this.page, // 传入页码 size: this.size, // 传入每页条数 search: this.search, // 传入搜索的对象 }); console.log(this.list, result) this.total = result.total; if (this.list.length == 0 && result.length == 0) { this.shownoData = false } else { this.shownoData = true } this.list = this.list.concat(result) // 判断是否全部加载完成 if (this.total == this.list.length) { this.finished = true; this.loading = 'nomore'; } else { this.loading = 'loadmore'; } }, handelDetail(record, type) { switch (type) { case 'internship': this.$u.route({ url: `pages/main/internship/intershipInfo/intershipInfo?id=${record.formId}` }) break; case 'credit': this.$u.route({ url: `pages/main/internship/achievementDetail/achievementDetail?id=${record.formId}` }) break; } }, workSearch() { uni.hideKeyboard(); this.works = [] this.worksloadData() }, lower() { setTimeout(() => { this.worksloadData(true); }, 200) }, worksloadData(e) { let params = {} // this.loading = 'loading' if (e) { if (this.total <= this.works.length) { // this.loading = 'nomore' return } this.workspage++ } else { this.workspage = 1 } params['pageNumber'] = this.workspage console.warn(this.sxsearch) if (this.sxsearch) { params['keyWord'] = this.sxsearch } getPlanListApi(params).then(async res => { if (res) { this.total = res.total // this.loading = 'loadmore' this.works = this.works.concat(res.records) } }) }, popupSelItem(item) { this.planId = item.id; this.finished = false; getInternshipProcessDetailApi({ studentId: this.studentId, planId: this.planId, }).then(data => { if (data) { this.detail = data; this.show = false } }) }, } } </script> <style lang="scss" scoped> .report_detail { width: 100%; min-height: 100%; height: auto; background-color: #F7F7F7; padding: 20rpx 0 0 0; .box { width: 630rpx; margin: 20rpx auto; padding: 30rpx 30rpx 12rpx 30rpx; border-radius: 12rpx; background-color: #FFFFFF; .title { font-size: 32rpx; line-height: 32rpx; color: #202131; margin: 0 0 30rpx 0; } .title::before { content: ""; display: inline-block; width: 6rpx; height: 32rpx; background-color: var(--primary-color); margin: 0 12rpx 0 0; position: relative; top: 4rpx; border-radius: 8rpx; } .item { margin: 0 0 24rpx 0; text:first-child { display: inline-block; width: 112rpx; text-align: justify; text-align-last: justify; font-size: 28rpx; line-height: 48rpx; color: #909097; vertical-align: top; } text:last-child { display: inline-block; width: 440rpx; font-size: 28rpx; line-height: 48rpx; color: #202131; margin: 0 0 0 78rpx; } } .item_icon { margin: 0 0 24rpx 0; display: flex; // flex-flow: row nowrap; align-items: center; justify-content: space-between; margin: 0 0 50rpx 0; text { // width: 112rpx; font-size: 28rpx; line-height: 32rpx; color: #909097; } view { display: flex; flex-flow: row nowrap; text { display: inline-block; width: auto; font-size: 28rpx; line-height: 32rpx; color: #202131; margin: 0 0 0 78rpx; } } } } .form_info { .info { display: flex; flex-flow: row nowrap; align-items: center; margin: 0 0 30rpx 0; .avatar { width: 94rpx; height: 94rpx; padding: 0 8rpx; border-radius: 4rpx; background-color: var(--primary-color); font-size: 24rpx; line-height: 94rpx; color: #FFFFFF; text-align: center; } .name { font-size: 32rpx; line-height: 44rpx; color: #202131; font-weight: 500; margin: 0 20rpx; } .number { font-size: 28rpx; line-height: 32rpx; color: #909097; } } .company { display: flex; flex-flow: row nowrap; margin: 0 0 30rpx 0; text { width: 120rpx; font-size: 28rpx; line-height: 32rpx; color: #909097; } text:last-child { width: 470rpx; color: #202131; margin: 0 0 0 30rpx; } } } .tab_box { position: relative; .tab { width: 600rpx; } .u-icon { width: 32rpx; position: absolute; top: 30rpx; right: 30rpx; } } .practical_courses { .list_box { padding: 30rpx 0 50rpx 0; .item { position: relative; width: 630rpx; margin: 0 auto 30rpx; padding: 30rpx; border-radius: 12rpx; background-color: #FFFFFF; .title_box { display: flex; flex-flow: row nowrap; .title { font-size: 32rpx; line-height: 44rpx; color: #202131; margin: 0 0 20rpx 0; font-weight: 500; } .title::before { content: ""; display: inline-block; width: 6rpx; height: 32rpx; background-color: var(--primary-color); margin: 0 12rpx 0 0; position: relative; top: 4rpx; border-radius: 8rpx; } .credit { font-size: 28rpx; line-height: 44rpx; color: #909097; margin: 0 0 0 32rpx; } } .company_box { .company { display: flex; flex-flow: row nowrap; font-size: 32rpx; line-height: 44rpx; color: #202131; margin: 0 0 20rpx 0; font-weight: 500; text { margin: 0 0 0 8rpx; } } .address { display: flex; flex-flow: row nowrap; font-size: 28rpx; line-height: 32rpx; color: #909097; margin: 0 0 20rpx 0; text { margin: 0 0 0 8rpx; } } } .projiect_item { width: 570rpx; border-radius: 12rpx; background-color: #F8F8FB; margin: 0 0 20rpx 0; padding: 30rpx; .projiect { display: flex; flex-flow: row nowrap; margin: 0 0 30rpx 0; text { width: 120rpx; font-size: 28rpx; line-height: 32rpx; color: #909097; text-align: justify; text-align-last: justify; } text:last-child { width: 420rpx; color: #202131; margin: 0 0 0 30rpx; text-align: start; text-align-last: start; } } } } } } .popup_search { width: 640rpx; position: relative; .content { padding: 0 40rpx; .title { padding: 24rpx 0; font-size: 28rpx; line-height: 36rpx; color: #202131; } .scroll { max-height: 60vh; .item { view { display: flex; flex-flow: row wrap; align-items: center; width: 500rpx; height: 74rpx; border-radius: 4rpx; border: 2rpx solid #C1C1C9; margin: 0 10rpx 20rpx; font-size: 24rpx; line-height: 32rpx; color: #C0C0C9; padding: 16rpx 20rpx; } .selectItem { background-color: var(--primary-color); color: #FFFFFF; border: 2rpx solid var(--primary-color); } } } .time { padding: 40rpx 0 0 0; } .switch { display: flex; flex-flow: row nowrap; justify-content: space-between; padding: 40rpx 0 0 0; text { font-size: 28rpx; line-height: 36rpx; color: #202131; } } } .footer { width: 560rpx; height: 96rpx; padding: 28rpx 40rpx; background: #FFFFFF; position: fixed; bottom: 0; right: 0; z-index: 99; border-top: 2rpx solid #E2E2E8; view { display: inline-block; } .left_btn { width: 194rpx; margin: 0 20rpx 0 0; } .right_btn { width: 346rpx; } } } .popup { height: 500px; padding: 19px 16px; .title { font-size: 18px; font-family: PingFangSC-Medium, PingFang SC; font-weight: 500; color: #000000; } .close { width: 22px; height: 22px; } .item_box { border-radius: 4px; margin: 0 0 48rpx; .item_title { height: 20px; font-size: 14px; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: rgba(0, 0, 0, 0.65); line-height: 20px; } } .no_data { width: 100%; margin-top: 310rpx; .text_black_28 { font-size: 14px; font-family: PingFangSC-Light, PingFang SC; font-weight: 300; color: rgba(0, 0, 0, 0.65); text-align: center; } } } } </style>