|
|
@@ -8,10 +8,21 @@
|
|
|
-->
|
|
|
<template>
|
|
|
<div class="instr-detail">
|
|
|
- <van-swipe v-if="noticeInfo.noticeTitle" class="my-swipe" :autoplay="5000" :show-indicators="false" vertical height="30">
|
|
|
+ <van-swipe
|
|
|
+ v-if="noticeInfo.noticeTitle"
|
|
|
+ class="my-swipe"
|
|
|
+ :autoplay="5000"
|
|
|
+ :show-indicators="false"
|
|
|
+ vertical
|
|
|
+ height="30"
|
|
|
+ >
|
|
|
<van-swipe-item @click="state.popupShow = true">
|
|
|
<div class="flex">
|
|
|
- <van-icon name="volume-o" class="mr4" :size="20" />
|
|
|
+ <van-icon
|
|
|
+ name="volume-o"
|
|
|
+ class="mr4"
|
|
|
+ :size="20"
|
|
|
+ />
|
|
|
{{ noticeInfo.noticeTitle }}
|
|
|
</div>
|
|
|
</van-swipe-item>
|
|
|
@@ -19,7 +30,11 @@
|
|
|
<header class="flex">
|
|
|
<div class="h100">
|
|
|
<!-- <img :showLoading="true" :src="state.instDetail.instPicture" width="80px" height="80px" /> -->
|
|
|
- <van-image width="80px" height="80px" :src="state.instDetail.instPicture" />
|
|
|
+ <van-image
|
|
|
+ width="80px"
|
|
|
+ height="80px"
|
|
|
+ :src="state.instDetail.instPicture"
|
|
|
+ />
|
|
|
</div>
|
|
|
<div class="i-right ml10">
|
|
|
<div class="h100 flex flex-top flex-column flex-between">
|
|
|
@@ -28,23 +43,48 @@
|
|
|
</div>
|
|
|
<footer>
|
|
|
<div class="flex flex-top mb4 mt-auto">
|
|
|
- <img class="i-r-icon" src="../../assets/img/user.png" v-if="state.instDetail.instHeadName" />
|
|
|
+ <img
|
|
|
+ class="i-r-icon"
|
|
|
+ src="../../assets/img/user.png"
|
|
|
+ v-if="state.instDetail.instHeadName"
|
|
|
+ />
|
|
|
<div class="detailTxt">{{ state.instDetail.instHeadName }}</div>
|
|
|
</div>
|
|
|
<div class="flex flex-top">
|
|
|
- <img class="i-r-icon" src="../../assets/img/address.png" v-if="state.instDetail.placeAddress" />
|
|
|
- <div class="detailTxt">{{ state.instDetail.placeAddress + setLaboratoryName(state.instDetail.laboratoryName) }}</div>
|
|
|
+ <img
|
|
|
+ class="i-r-icon"
|
|
|
+ src="../../assets/img/address.png"
|
|
|
+ v-if="state.instDetail.placeAddress"
|
|
|
+ />
|
|
|
+ <div class="detailTxt">
|
|
|
+ {{ state.instDetail.placeAddress + setLaboratoryName(state.instDetail.laboratoryName) }}
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</footer>
|
|
|
</div>
|
|
|
</div>
|
|
|
</header>
|
|
|
- <van-tabs v-model:active="active" @change="tabChange">
|
|
|
- <van-tab title="仪器信息" name="info"></van-tab>
|
|
|
- <van-tab title="待审核" name="approval"></van-tab>
|
|
|
- <van-tab title="历史申请" name="history"></van-tab>
|
|
|
+ <van-tabs
|
|
|
+ v-model:active="active"
|
|
|
+ @change="tabChange"
|
|
|
+ >
|
|
|
+ <van-tab
|
|
|
+ title="仪器信息"
|
|
|
+ name="info"
|
|
|
+ ></van-tab>
|
|
|
+ <van-tab
|
|
|
+ title="待审核"
|
|
|
+ name="approval"
|
|
|
+ ></van-tab>
|
|
|
+ <van-tab
|
|
|
+ title="历史申请"
|
|
|
+ name="history"
|
|
|
+ ></van-tab>
|
|
|
</van-tabs>
|
|
|
- <div v-if="active === 'info'" class="content">
|
|
|
+ <div
|
|
|
+ v-if="active === 'info'"
|
|
|
+ class="content"
|
|
|
+ >
|
|
|
<div class="card">
|
|
|
<h4>仪器信息</h4>
|
|
|
<ul>
|
|
|
@@ -90,6 +130,20 @@
|
|
|
<h4>主要功能</h4>
|
|
|
<div class="text">{{ state.instDetail.instFunctFeat }}</div>
|
|
|
</div>
|
|
|
+ <div
|
|
|
+ class="card"
|
|
|
+ v-if="isNeedGrant"
|
|
|
+ @click="applicationAuth"
|
|
|
+ >
|
|
|
+ <h4>资质申请</h4>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class="card"
|
|
|
+ v-if="isNeedGrant"
|
|
|
+ @click="applyTraining"
|
|
|
+ >
|
|
|
+ <h4>培训申请</h4>
|
|
|
+ </div>
|
|
|
<!-- <div class="card">
|
|
|
<h4>相关附件</h4>
|
|
|
<template v-for="item in state.instFiles">
|
|
|
@@ -99,22 +153,78 @@
|
|
|
</template>
|
|
|
</div> -->
|
|
|
</div>
|
|
|
- <van-list v-else v-model:loading="state.loading" :finished="state.finished" finished-text="没有更多了" @load="onLoad">
|
|
|
+ <van-list
|
|
|
+ v-else
|
|
|
+ v-model:loading="state.loading"
|
|
|
+ :finished="state.finished"
|
|
|
+ finished-text="没有更多了"
|
|
|
+ @load="onLoad"
|
|
|
+ >
|
|
|
<van-cell v-for="item in state.list">
|
|
|
<template #default>
|
|
|
<div class="list">
|
|
|
<header class="flex justify-between">
|
|
|
<strong class="title">{{ item.userName }}的预约</strong>
|
|
|
- <van-tag v-if="item.appointStatus == '10'" type="default">待审核</van-tag>
|
|
|
- <van-tag v-else-if="item.appointStatus == '11'" type="warning">已退回</van-tag>
|
|
|
- <van-tag v-else-if="item.appointStatus == '20'" type="success">已通过</van-tag>
|
|
|
- <van-tag v-else-if="item.appointStatus == '30'" type="danger">已驳回</van-tag>
|
|
|
- <van-tag v-else-if="item.appointStatus == '40'" type="warning">已取消</van-tag>
|
|
|
- <van-tag v-else-if="item.appointStatus == '50'" type="default">已上机</van-tag>
|
|
|
- <van-tag v-else-if="item.appointStatus == '60'" type="primary">已完成</van-tag>
|
|
|
- <van-tag v-else-if="item.appointStatus == '70'" type="warning">审核超时</van-tag>
|
|
|
- <van-tag v-else-if="item.appointStatus == '80'" type="danger">超时取消</van-tag>
|
|
|
- <van-tag v-else-if="item.appointStatus == '90'" type="danger">超时未上机</van-tag>
|
|
|
+ <van-tag
|
|
|
+ v-if="item.appointStatus == '10'"
|
|
|
+ type="default"
|
|
|
+ >
|
|
|
+ 待审核
|
|
|
+ </van-tag>
|
|
|
+ <van-tag
|
|
|
+ v-else-if="item.appointStatus == '11'"
|
|
|
+ type="warning"
|
|
|
+ >
|
|
|
+ 已退回
|
|
|
+ </van-tag>
|
|
|
+ <van-tag
|
|
|
+ v-else-if="item.appointStatus == '20'"
|
|
|
+ type="success"
|
|
|
+ >
|
|
|
+ 已通过
|
|
|
+ </van-tag>
|
|
|
+ <van-tag
|
|
|
+ v-else-if="item.appointStatus == '30'"
|
|
|
+ type="danger"
|
|
|
+ >
|
|
|
+ 已驳回
|
|
|
+ </van-tag>
|
|
|
+ <van-tag
|
|
|
+ v-else-if="item.appointStatus == '40'"
|
|
|
+ type="warning"
|
|
|
+ >
|
|
|
+ 已取消
|
|
|
+ </van-tag>
|
|
|
+ <van-tag
|
|
|
+ v-else-if="item.appointStatus == '50'"
|
|
|
+ type="default"
|
|
|
+ >
|
|
|
+ 已上机
|
|
|
+ </van-tag>
|
|
|
+ <van-tag
|
|
|
+ v-else-if="item.appointStatus == '60'"
|
|
|
+ type="primary"
|
|
|
+ >
|
|
|
+ 已完成
|
|
|
+ </van-tag>
|
|
|
+ <van-tag
|
|
|
+ v-else-if="item.appointStatus == '70'"
|
|
|
+ type="warning"
|
|
|
+ >
|
|
|
+ 审核超时
|
|
|
+ </van-tag>
|
|
|
+ <van-tag
|
|
|
+ v-else-if="item.appointStatus == '80'"
|
|
|
+ type="danger"
|
|
|
+ >
|
|
|
+ 超时取消
|
|
|
+ </van-tag>
|
|
|
+ <van-tag
|
|
|
+ v-else-if="item.appointStatus == '90'"
|
|
|
+ type="danger"
|
|
|
+ >
|
|
|
+ 超时未上机
|
|
|
+ </van-tag>
|
|
|
</header>
|
|
|
<p class="inst-title">
|
|
|
<span>预约仪器</span>
|
|
|
@@ -122,7 +232,11 @@
|
|
|
</p>
|
|
|
<p class="inst-title">
|
|
|
<span>预约时间</span>
|
|
|
- <span class="title ml8">{{ formatDate(new Date(item.startTime), 'mm-dd HH:MM') }}~{{ formatDate(new Date(item.endTime), 'mm-dd HH:MM') }}</span>
|
|
|
+ <span class="title ml8">
|
|
|
+ {{ formatDate(new Date(item.startTime), 'mm-dd HH:MM') }}~{{
|
|
|
+ formatDate(new Date(item.endTime), 'mm-dd HH:MM')
|
|
|
+ }}
|
|
|
+ </span>
|
|
|
</p>
|
|
|
<p class="inst-title">
|
|
|
<span>预约时长</span>
|
|
|
@@ -148,34 +262,77 @@
|
|
|
</template>
|
|
|
</van-cell>
|
|
|
</van-list>
|
|
|
- <van-back-top target=".instr-detail" bottom="10vh" />
|
|
|
+ <van-back-top
|
|
|
+ target=".instr-detail"
|
|
|
+ bottom="10vh"
|
|
|
+ />
|
|
|
</div>
|
|
|
<van-action-bar placeholder>
|
|
|
- <van-action-bar-icon icon="wap-home-o" text="首页" @click="onRouterPush('/home')" />
|
|
|
- <van-action-bar-icon icon="calendar-o" text="周视图" />
|
|
|
- <van-action-bar-icon :icon="state.instDetail.following ? 'star' : 'star-o'" :class="{ follow: state.instDetail.following }" :text="state.instDetail.following ? '取消收藏' : '收藏'" @click="handleFollowInst" />
|
|
|
- <van-action-bar-button type="primary" text="立即预约" @click="onAppoint" />
|
|
|
+ <van-action-bar-icon
|
|
|
+ icon="wap-home-o"
|
|
|
+ text="首页"
|
|
|
+ @click="onRouterPush('/home')"
|
|
|
+ />
|
|
|
+ <van-action-bar-icon
|
|
|
+ icon="calendar-o"
|
|
|
+ text="周视图"
|
|
|
+ />
|
|
|
+ <van-action-bar-icon
|
|
|
+ :icon="state.instDetail.following ? 'star' : 'star-o'"
|
|
|
+ :class="{ follow: state.instDetail.following }"
|
|
|
+ :text="state.instDetail.following ? '取消收藏' : '收藏'"
|
|
|
+ @click="handleFollowInst"
|
|
|
+ />
|
|
|
+ <van-action-bar-button
|
|
|
+ type="primary"
|
|
|
+ text="立即预约"
|
|
|
+ @click="onAppoint"
|
|
|
+ />
|
|
|
</van-action-bar>
|
|
|
<!-- 通知 -->
|
|
|
- <van-popup v-model:show="state.popupShow" round :closeable="true" position="top" :style="{ padding: '20px' }">
|
|
|
+ <van-popup
|
|
|
+ v-model:show="state.popupShow"
|
|
|
+ round
|
|
|
+ :closeable="true"
|
|
|
+ position="top"
|
|
|
+ :style="{ padding: '20px' }"
|
|
|
+ >
|
|
|
<h4>{{ noticeInfo.noticeTitle }}</h4>
|
|
|
- <div class="notice-container" v-html="noticeInfo.noticeContent"></div>
|
|
|
+ <div
|
|
|
+ class="notice-container"
|
|
|
+ v-html="noticeInfo.noticeContent"
|
|
|
+ ></div>
|
|
|
</van-popup>
|
|
|
<!-- 申请须知 -->
|
|
|
- <van-popup v-model:show="state.needToKnowShow" round :closeable="true" position="bottom" :style="{ height: '90vh' }">
|
|
|
+ <van-popup
|
|
|
+ v-model:show="state.needToKnowShow"
|
|
|
+ round
|
|
|
+ :closeable="true"
|
|
|
+ position="bottom"
|
|
|
+ :style="{ height: '90vh' }"
|
|
|
+ >
|
|
|
<div class="need-to-know">
|
|
|
<h4 class="mt8 mb8">申请须知</h4>
|
|
|
<p>{{ state.instDetail.applicationNotes }}</p>
|
|
|
<footer>
|
|
|
- <van-button class="w100" type="primary" round @click="confirmAppoint">我知道了</van-button>
|
|
|
+ <van-button
|
|
|
+ class="w100"
|
|
|
+ type="primary"
|
|
|
+ round
|
|
|
+ @click="confirmAppoint"
|
|
|
+ >
|
|
|
+ 我知道了
|
|
|
+ </van-button>
|
|
|
</footer>
|
|
|
</div>
|
|
|
</van-popup>
|
|
|
+ <AddAuthDialog ref="addAuthDialogRef" />
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
import to from 'await-to-js'
|
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
|
+ import { ElMessageBox, ElMessage } from 'element-plus'
|
|
|
import { useInstrApi } from '/@/api/instr'
|
|
|
import { useInstDocApi } from '/@/api/instr/document'
|
|
|
import { onMounted, reactive, ref } from 'vue'
|
|
|
@@ -185,6 +342,10 @@
|
|
|
import { useNoticeApi } from '/@/api/instr/notice'
|
|
|
import { useUseAppointApi } from '/@/api/instr/useAppoint'
|
|
|
import { useBlackApi } from '/@/api/blacklist'
|
|
|
+ import AddAuthDialog from './addAuthorization/index.vue'
|
|
|
+ import { useUserInfos } from '/@/hooks/useUserInfos'
|
|
|
+ import { useTrainingApi } from '/@/api/instr/inst/training'
|
|
|
+
|
|
|
const route = useRoute()
|
|
|
const router = useRouter()
|
|
|
const instApi = useInstrApi()
|
|
|
@@ -192,13 +353,14 @@
|
|
|
const noticeApi = useNoticeApi()
|
|
|
const useAppointApi = useUseAppointApi()
|
|
|
const blacklistApi = useBlackApi()
|
|
|
+ const trainingApi = useTrainingApi()
|
|
|
const active = ref('info')
|
|
|
const state = reactive({
|
|
|
detailsLoading: false,
|
|
|
instStatus: {
|
|
|
10: '正常',
|
|
|
20: '故障',
|
|
|
- 30: '报废'
|
|
|
+ 30: '报废',
|
|
|
},
|
|
|
instDetail: {} as any,
|
|
|
instFiles: [] as any[],
|
|
|
@@ -208,13 +370,26 @@
|
|
|
pageNum: 1,
|
|
|
pageSize: 10,
|
|
|
instId: 0,
|
|
|
- appointStatus: []
|
|
|
+ appointStatus: [],
|
|
|
},
|
|
|
list: [] as any[],
|
|
|
popupShow: false,
|
|
|
- needToKnowShow: false
|
|
|
+ needToKnowShow: false,
|
|
|
})
|
|
|
const noticeInfo = ref({ noticeTitle: '', noticeContent: '' })
|
|
|
+
|
|
|
+ const isNeedGrant = ref(false)
|
|
|
+
|
|
|
+ const addAuthDialogRef = ref()
|
|
|
+
|
|
|
+ const { userInfos } = useUserInfos()
|
|
|
+
|
|
|
+ const getNeedGrant = async (instId: number) => {
|
|
|
+ const [err, res]: ToResponse = await to(useAppointApi.getNeedGrant({ instId }))
|
|
|
+ if (err) return
|
|
|
+ isNeedGrant.value = res?.data
|
|
|
+ }
|
|
|
+
|
|
|
// 获取仪器详情
|
|
|
const getDetail = async (id: number) => {
|
|
|
state.detailsLoading = true
|
|
|
@@ -231,7 +406,7 @@
|
|
|
const param = {
|
|
|
pageNum: 1,
|
|
|
pageSize: 1,
|
|
|
- instId: state.instDetail.instId
|
|
|
+ instId: state.instDetail.instId,
|
|
|
}
|
|
|
const [err, res]: ToResponse = await to(noticeApi.list({ ...param }))
|
|
|
if (err) return
|
|
|
@@ -239,7 +414,9 @@
|
|
|
}
|
|
|
// 附件列表
|
|
|
const getDocs = async () => {
|
|
|
- const [err, res]: ToResponse = await to(instDocApi.list({ noPage: true, instId: state.instDetail.instId, docType: '' }))
|
|
|
+ const [err, res]: ToResponse = await to(
|
|
|
+ instDocApi.list({ noPage: true, instId: state.instDetail.instId, docType: '' }),
|
|
|
+ )
|
|
|
if (err) return
|
|
|
state.instFiles = res?.data.list || []
|
|
|
}
|
|
|
@@ -256,7 +433,7 @@
|
|
|
// 创建a标签 实现下载
|
|
|
const downloadFun = async (blobFile, fileName) => {
|
|
|
let blob = new Blob([blobFile], {
|
|
|
- type: 'application/pdf;charset=UTF-8'
|
|
|
+ type: 'application/pdf;charset=UTF-8',
|
|
|
})
|
|
|
// @ts-ignore
|
|
|
if (window.navigator.msSaveOrOpenBlob) {
|
|
|
@@ -281,7 +458,7 @@
|
|
|
pageNum: 1,
|
|
|
pageSize: 10,
|
|
|
instId: state.instDetail.id,
|
|
|
- appointStatus: name === 'approval' ? ['10'] : []
|
|
|
+ appointStatus: name === 'approval' ? ['10'] : [],
|
|
|
}
|
|
|
onLoad()
|
|
|
}
|
|
|
@@ -349,12 +526,41 @@
|
|
|
const onRouterPush = (val: string, params?: any) => {
|
|
|
router.push({
|
|
|
path: val,
|
|
|
- query: { ...params }
|
|
|
+ query: { ...params },
|
|
|
})
|
|
|
}
|
|
|
+
|
|
|
+ const applicationAuth = async () => {
|
|
|
+ console.log('applicationAuth')
|
|
|
+ addAuthDialogRef.value.openDialog('personal', state.instDetail)
|
|
|
+ }
|
|
|
+
|
|
|
+ const applyTraining = () => {
|
|
|
+ console.log('applyTraining')
|
|
|
+ ElMessageBox.confirm('确认发起培训申请?', '提示', {
|
|
|
+ confirmButtonText: '确认',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning',
|
|
|
+ })
|
|
|
+ .then(async () => {
|
|
|
+ const params = {
|
|
|
+ instCode: state.instDetail.instCode,
|
|
|
+ instId: state.instDetail.id,
|
|
|
+ instName: state.instDetail.instName,
|
|
|
+ userId: userInfos.value.id,
|
|
|
+ userName: userInfos.value.nickName,
|
|
|
+ }
|
|
|
+ const [err]: ToResponse = await to(trainingApi.add({ ...params }))
|
|
|
+ if (err) return
|
|
|
+ ElMessage.success('培训申请提交成功')
|
|
|
+ })
|
|
|
+ .catch(() => {})
|
|
|
+ }
|
|
|
+
|
|
|
onMounted(() => {
|
|
|
const id = route.query.id ? +route.query.id : 0
|
|
|
getDetail(id)
|
|
|
+ getNeedGrant(id)
|
|
|
})
|
|
|
</script>
|
|
|
|