Commit bbebec09 authored by songrui's avatar songrui

tab组件、图片上传组件

parent 36783f76
...@@ -52,7 +52,7 @@ export default { ...@@ -52,7 +52,7 @@ export default {
if (!token) { if (!token) {
token = sessionStorage.getItem('token') token = sessionStorage.getItem('token')
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
token = '4ef7a32e-c217-44b6-ac5d-8ad9a91d38a0' token = 'c44236d5-f78e-4b8c-a30b-d70018ce3c74'
} }
} }
if (token) { if (token) {
......
<template>
<div class="doc-image">
<div v-if="isPdf" class="p-2 flex items-center view-pdf">
<doc-icon type="doc-PDF" style="font-size: .48rem" class="shrink-0"/>
<span class="grow px-4 text-ellipsis">{{name}}</span>
<span class="close-btn" @click="removeBtn" v-if="remove">
<doc-icon type="close-circle" />
</span>
</div>
<div class="view-img" v-if="status==='success' && !isPdf">
<img :src="src" :alt="name"
:loading="loading" >
</div>
<template v-if="!isPdf">
<div class="doc-image-wrapper" v-if="status==='loading'">
<slot name="placeholder">
<div class="doc-image-default">加载中...</div>
</slot>
</div>
<div class="doc-image-wrapper" v-if="status==='fail'">
<slot name="fail">
<div class="doc-image-default">加载失败</div>
</slot>
</div>
<span class="close-btn" @click="removeBtn" v-if="remove">
<doc-icon type="close-circle" />
</span>
</template>
</div>
</template>
<script>
export default {
name: 'doc-image',
props: {
src: String,
// 浏览器应当如何加载该图像
// img标签中的属性 需要浏览器支持
// https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/img
// eager 立即加载图像
// lazy 延迟加载图像,直到它和视口接近到一个计算得到的距离
loading: String,
// 开启删除功能
remove: Boolean,
// 处理pdf预览
isPdf: Boolean,
name: String
},
emits: ['removeBtn'],
data() {
return {
// 图片加载状态 loading | fail | success
status: 'loading',
imgStyle: {},
// viewer显示
visible: false,
// 按键界面显示
btVisible: false
}
},
methods: {
loadImage() {
if (this.isPdf) {
this.status = 'success'
return
}
const image = new Image()
image.onload = () => {
this.show = true
this.status = 'success'
}
image.onerror = (err) => {
console.warn('doc-image', err)
this.show = false
this.status = 'fail'
}
this.status = 'loading'
image.src = this.src
},
removeBtn() {
this.btVisible = false
this.$emit('onRemove', this.src)
}
},
watch: {
src: {
handler(val) {
if (val) {
this.loadImage()
}
},
immediate: true
}
}
}
</script>
<style lang="less" scoped>
.doc-image {
display: inline-block;
width: 100%;
height: 100%;
position: relative;
.view-img {
width: 100%;
height: 100%;
min-height: 90px;
img {
width: 100%;
height: 100%;
object-fit: contain;
}
}
.view-pdf {
width: 100%;
min-height: 48px;
overflow-y: hidden;
border-radius: 8px;
border: 1px solid #EEEEEE;
.close-btn {
top: 50%;
right: 8px;
transform: translateY(-50%);
}
}
.close-btn {
position: absolute;
font-size: 16px;
top: -8px;
right: -8px;
}
}
.doc-image-wrapper {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.doc-image-default {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
background: #f5faf7;
color: #a8abb2;
vertical-align: middle;
user-select: none;
}
</style>
...@@ -5,17 +5,14 @@ ...@@ -5,17 +5,14 @@
<doc-icon type="doc-upload" class="mr-2 text-16"/> <doc-icon type="doc-upload" class="mr-2 text-16"/>
<span>{{ btText }}</span> <span>{{ btText }}</span>
</div> </div>
<div class="flex flex-wrap justify-between mt-4 image-box"> <div class="flex flex-wrap mt-4 image-box">
<div v-for="item in innerImage" :key="item.id"> <div v-for="item in innerImage.filter(e => e.fileType != 'pdf')" :key="item.id"
<div v-if="item.fileType === 'pdf'" class=""> class="item-img">
<doc-icon type="doc-PDF" /> <DocImage :src="item.url" remove/>
</div> </div>
<div v-else> <div v-for="item in innerImage.filter(e => e.fileType == 'pdf')" :key="item.id"
<img src="@/assets/image/doctor/empty.png" style="width: 100%"/> class="item-pdf">
</div> <DocImage isPdf :src="item.url" name="pdf文件名称" remove/>
<span class="close-btn" @click="removeImage(item)">
<doc-icon type="close-circle" />
</span>
</div> </div>
</div> </div>
<input type="file" <input type="file"
...@@ -28,10 +25,16 @@ ...@@ -28,10 +25,16 @@
</template> </template>
<script> <script>
import DocImage from './DocImage.vue'
import { showToast } from 'vant' import { showToast } from 'vant'
const testUrl = 'https://beta-tumour.zmnyjk.com/chronic-admin/file-proxy/chronic/20241125/1732502450600434289.png?e=1732610606&token=yrkyCAltqk1WVrw1ZNWUl5F5gLxE0O8LJ0Vq4hzi:RYbssXLQIEX6KTcVk5u4tWaxb9o='
export default { export default {
name: 'DocImageUpload', name: 'DocImageUpload',
components:{
DocImage
},
props: { props: {
// 上传描述 // 上传描述
description: { default: '温馨提示:请上传JPG、PNG格式图片,文件大小不超过5M' }, description: { default: '温馨提示:请上传JPG、PNG格式图片,文件大小不超过5M' },
...@@ -70,9 +73,10 @@ export default { ...@@ -70,9 +73,10 @@ export default {
this.innerImage = [...this.imageData] this.innerImage = [...this.imageData]
} else { } else {
this.innerImage = [ this.innerImage = [
{ fileType: 'pdf', id: 1 }, { fileType: 'pdf', id: 1, url: testUrl },
{ fileType: 'png', id: 2 }, { fileType: 'png', id: 2, url: testUrl },
{ fileType: 'png', id: 3 } { fileType: 'png', id: 3, url: testUrl },
{ fileType: 'png', id: 4, url: testUrl },
] ]
} }
}, },
...@@ -153,20 +157,21 @@ export default { ...@@ -153,20 +157,21 @@ export default {
border-radius: 8px; border-radius: 8px;
} }
.image-box { .image-box {
row-gap: 8px;
column-gap: 12px;
.item-img {
width: calc(33.3vw - 8px);
}
.item-pdf {
width: 100%;
}
>div { >div {
width: calc(33.3vw - 8px); width: calc(33.3vw - 8px);
position: relative; position: relative;
border: 1px solid #999;
border-radius: 2px; border-radius: 2px;
img { img {
object-fit: contain; object-fit: contain;
} }
} }
.close-btn {
position: absolute;
font-size: 16px;
top: -8px;
right: -8px;
}
} }
</style> </style>
<template>
<div class="workbench"></div>
</template>
<script>
export default {
}
</script>
<style lang="less" scoped>
</style>
...@@ -14,6 +14,27 @@ ...@@ -14,6 +14,27 @@
<h4>upload</h4> <h4>upload</h4>
<DocImageUpload /> <DocImageUpload />
<h4>work-tab</h4>
<div class="work-tab">
<div class="back"></div>
<div class="flex work-tab-inner">
<div class="item">工作记录</div>
<div class="item" active>待筛查记录</div>
<div class="item" >慢病待随访</div>
</div>
</div>
<h4>tab</h4>
<van-tabs shrink type="card" class="doc-tab-round">
<van-tab v-for="index in 4" :title="'标签 ' + index" :key="index"></van-tab>
</van-tabs>
<h4>button</h4>
<van-button round size="small" class="doc-btn-primary">修改</van-button>
<van-button round size="small" class="doc-btn-red">删除</van-button>
</div> </div>
</template> </template>
...@@ -51,5 +72,123 @@ export default { ...@@ -51,5 +72,123 @@ export default {
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
:deep(.doc-tab-round) {
.van-tabs__nav--card {
column-gap: 10px;
border: 0;
margin: 0;
}
.van-tab--card {
border: 0;
border-radius: 40px;
background: #fff;
color: #262626;
font-size: 14px;
line-height: 28px;
padding: 0 10px;
transition: all .2s;
}
.van-tab--card.van-tab--active {
color: #fff;
background: var(--van-primary-color);
font-weight: 500;
}
}
.doc-btn {
border: 0;
padding: 4px 12px;
height: 26px;
}
.doc-btn-primary {
.doc-btn();
color: var(--van-primary-color);
background: #F0F3FF;
}
.doc-btn-red {
.doc-btn();
color: #FF4D4F;
background: #FFF3F0;
}
.work-tab {
background: #C6DBF9;
padding-top: 10px;
position: relative;
.work-tab-inner {
align-items: flex-end;
position: relative;
}
.back {
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 42px;
background-color: #E7F1FF;
border-top-left-radius: 12px;
border-top-right-radius: 12px;
}
.item {
// flex-grow: 1;
position: relative;
padding: 0 16px;
height: 42px;
line-height: 42px;
text-align: center;
&:first-child {
border-top-left-radius: 12px;
}
&:last-child {
border-top-right-radius: 12px;
}
}
.item:first-child[active] {
border-top-left-radius: 12px;
&::before {
display: none;
}
}
.item:last-child[active] {
border-top-right-radius: 12px;
&::after {
display: none;
}
}
.item[active] {
background-color: #F8FAFC;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
font-size: 16px;
height: 46px;
line-height: 46px;
&::after {
content: '';
display: inline-block;
position: absolute;
right: -26px;
bottom: 0;
background: url('@/assets/image/doctor/tab-bg.png') no-repeat;
background-size: auto 100%;
background-position-x: -20px;
height: 100%;
width: 34px;
z-index: 1;
}
&::before {
content: '';
display: inline-block;
position: absolute;
left: -26px;
bottom: 0;
background: url('@/assets/image/doctor/tab-bg.png') no-repeat;
background-size: auto 100%;
background-position-x: -20px;
height: 100%;
width: 34px;
z-index: 1;
transform: rotateY(180deg);
}
}
}
</style> </style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment