Commit 3b19241e authored by songrui's avatar songrui

多选组件;图片上传组件

parent b3398af9
<svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle opacity="0.8" cx="8.8335" cy="8.68945" r="8" fill="#1F1F1F"/>
<path d="M6.16699 6.02295L11.5003 11.3563" stroke="white" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11.5005 6.02295L6.16715 11.3563" stroke="white" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<svg width="20" height="21" viewBox="0 0 20 21" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="19" height="17" viewBox="0 0 19 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.75993 17.1936C5.98659 17.33 2.35807 16.7844 2.03068 13.5105C1.70329 10.2367 4.07684 9.1454 5.30454 9.00898C5.44085 7.23564 6.69562 3.68896 10.6243 3.68896C14.5529 3.68896 15.2622 7.23564 15.1258 9.00898C16.4899 9.41822 19.0544 10.9733 18.3997 13.9198C17.7449 16.8662 14.3073 17.33 12.6704 17.1936" stroke="#607FF0" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="bevel"/> <path d="M6.75993 15.1941C4.98659 15.3305 1.35807 14.7849 1.03068 11.511C0.703294 8.23717 3.07684 7.14588 4.30454 7.00947C4.44085 5.23613 5.69562 1.68945 9.62425 1.68945C13.5529 1.68945 14.2622 5.23613 14.1258 7.00947C15.4899 7.41871 18.0544 8.97379 17.3997 11.9203C16.7449 14.8667 13.3073 15.3305 11.6704 15.1941" stroke="#607FF0" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="bevel"/>
<path d="M7.72949 12.692L10.1849 10.2366M10.1849 10.2366L12.6403 12.692M10.1849 10.2366V17.1935" stroke="#607FF0" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/> <path d="M6.72949 10.6927L9.18489 8.2373M9.18489 8.2373L11.6403 10.6927M9.18489 8.2373V15.1943" stroke="#607FF0" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
</svg> </svg>
<template> <template>
<div class="check-btn"> <div class="flex flex-wrap check-btn">
<div v-for="item in options" :key="item[fieldNames.value]"
@click="onClick(item)"
:class="['py-2 px-3 shrink-0 check-btn-item',
{ 'check-btn-item-active': isSelect(item) },
{ 'check-btn-item-disabled': isDisabled(item) }]">
{{ item[fieldNames.text] }}
</div>
</div> </div>
</template> </template>
...@@ -8,11 +14,97 @@ ...@@ -8,11 +14,97 @@
export default { export default {
name: 'CheckBtn', name: 'CheckBtn',
props:{ props:{
value: [String, Number, Array],
// 选项
options: { default: () =>[] },
fieldNames: {
type: Object,
default: () => {
return {text: 'name', value: 'code'}
}
},
// 是否多选
multiple: Boolean
},
emits: ['update:value', 'change'],
data() {
return {
innerValue: undefined
}
},
created() {
this.init()
},
methods: {
init() {
this.innerValue = this.value
if (this.multiple) {
if (this.value != null && !Array.isArray(this.value)) {
console.warn('CheckBtn: multiple must be Array type')
}
this.innerValue = this.innerValue || []
}
},
onClick(item){
if (this.isDisabled(item)) {
return
}
if (this.multiple) {
if (this.innerValue.includes(item[this.fieldNames.value])) {
this.innerValue = this.innerValue.filter(e => e !== item[this.fieldNames.value])
} else {
this.innerValue.push(item[this.fieldNames.value])
}
} else {
this.innerValue = item[this.fieldNames.value]
}
this.$emit('update:value', this.innerValue)
this.$emit('change', this.innerValue, item)
},
// 是否选中
isSelect(item){
if (this.multiple) {
return this.innerValue.includes(item[this.fieldNames.value])
} else {
return item[this.fieldNames.value] === this.innerValue
}
},
isDisabled(item){
return item.disabled
}
},
watch: {
value: {
handler(value) {
this.innerValue = value
},
immediate: true
},
} }
} }
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.check-btn {
row-gap: 10px;
column-gap: 10px;
}
.check-btn-item {
border: 1px solid transparent;
background-color: #FAFAFA;
border-radius: 8px;
transition: all .2s;
}
.check-btn-item-active {
border: 1px solid var(--van-primary-color);
background-color: #F0F6FF;
color: var(--van-primary-color);
}
.check-btn-item-disabled {
background-color: #F0F6FF;
color: var(--van-primary-color);
// opacity: 0.5;
filter: grayscale(1);
}
</style> </style>
<template>
<div class="doc-image-upload">
<div class="text-12 description">{{ description }}</div>
<div class="mt-2 py-3 text-center upload-btn" @click="fileSelect">
<doc-icon type="doc-upload" class="mr-2 text-16"/>
<span>{{ btText }}</span>
</div>
<div class="flex flex-wrap justify-between mt-4 image-box">
<div v-for="item in innerImage" :key="item.id">
<div v-if="item.fileType === 'pdf'" class="">
<doc-icon type="doc-PDF" />
</div>
<div v-else>
<img src="@/assets/image/doctor/empty.png" style="width: 100%"/>
</div>
<span class="close-btn" @click="removeImage(item)">
<doc-icon type="close-circle" />
</span>
</div>
</div>
<input type="file"
accept=".jpg,.jpeg,.png,.pdf"
ref="fileElem"
style="display: none;"
@change="handleFiles"
:key="inputKey">
</div>
</template>
<script>
import { showToast } from 'vant'
export default {
name: 'DocImageUpload',
props: {
// 上传描述
description: { default: '温馨提示:请上传JPG、PNG格式图片,文件大小不超过5M' },
// 传入的img数据 { id, trueDownloadUrl }
imageData: { default: () => [] },
// 上传按键的文字
btText: { default: '上传图片' },
// 图片框大小
size: String,
// 上传最大数量
maxLength: { default: 1 },
lengthMessage: { default: '已达到图片上限,请移除后再上传' }
},
data() {
return {
// 内部图片对象
innerImage: [],
file: null,
spinning: false,
inputKey: '1',
// viewer显示
visible: false
}
},
computed: {
fileElem() {
return this.$refs['fileElem']
},
ids() {
return this.innerImage.map(e => e.id).join(',')
}
},
methods:{
init() {
if (this.imageData?.length) {
this.innerImage = [...this.imageData]
} else {
this.innerImage = [
{ fileType: 'pdf', id: 1 },
{ fileType: 'png', id: 2 },
{ fileType: 'png', id: 3 }
]
}
},
fileSelect() {
console.log(this.innerImage, this.maxLength)
if (this.innerImage?.length >= this.maxLength) {
showToast(this.lengthMessage)
return
}
const dom = this.$refs['fileElem']
if (dom) {
dom.click()
}
},
upload() {
let formData = new FormData()
formData.append('file', this.file)
this.spinning = true
fileUpload(formData).then(res => {
// this.$message.success('上传成功')
let result = res.data || {}
this.$emit('upload', result)
this.addImage(result)
this.inputKey = Math.random().toString(16).substring(2, 6)
this.$emit('change', this.ids, this.innerImage)
this.formItemContext.onFieldChange()
}).finally(() => {
this.spinning = false
})
},
handleFiles() {
let files = this.$refs['fileElem'].files
if (files.length <= 0) {
showToast('未选中文件,请尝试重新选择')
return
}
if (files[0].size / 1024 / 1024 > 5) {
showToast('图片大小不能超过5M')
return
}
this.file = files[0]
this.upload()
},
addImage(data = {}) {
if (!data.id) {
console.warn('addImage 文件为空')
return
}
if (!this.innerImage.find(e => e.id === data.id)) {
this.innerImage.push(data)
}
},
removeImage(item) {
if (!item) return
this.innerImage = this.innerImage.filter(e => e.id != item.id)
this.$emit('change', this.ids, this.innerImage)
}
},
watch: {
imageData: {
handler(value) {
this.init()
},
immediate: true
}
}
}
</script>
<style lang="less" scoped>
.description {
color: #A5AEBE;
}
.upload-btn {
color: var(--van-primary-color);
border: 1px solid #eee;
background-color: #FAFAFA;
border-radius: 8px;
}
.image-box {
>div {
width: calc(33.3vw - 8px);
position: relative;
border: 1px solid #999;
border-radius: 2px;
img {
object-fit: contain;
}
}
.close-btn {
position: absolute;
font-size: 16px;
top: -8px;
right: -8px;
}
}
</style>
...@@ -6,22 +6,42 @@ ...@@ -6,22 +6,42 @@
<span class="ml-2">{{unitData.value}}</span> <span class="ml-2">{{unitData.value}}</span>
</div> </div>
<DocUnit v-model:show="unitData.visible" v-model:value="unitData.value"/> <DocUnit v-model:show="unitData.visible" v-model:value="unitData.value"/>
<div class="flex items-center">
<h4>多选/单选按键</h4>
<span>{{ checkData }}</span>
</div>
<CheckBtn :options="checkOptions" v-model:value="checkData"/>
<h4>upload</h4>
<DocImageUpload />
</div> </div>
</template> </template>
<script> <script>
import DocUnit from '@/doctor/components/docUnit/DocUnit.vue' import DocUnit from '@/doctor/components/docUnit/DocUnit.vue'
import CheckBtn from '@/doctor/components/checkBtn/CheckBtn.vue'
import DocImageUpload from '@/doctor/components/docImageUpload/DocImageUpload.vue'
export default { export default {
components:{ components:{
DocUnit DocUnit,
CheckBtn,
DocImageUpload
}, },
data(){ data(){
return { return {
unitData: { unitData: {
visible: false, visible: false,
value: undefined value: undefined
} },
checkData: undefined,
checkOptions: [
{ name: '血常规', code: 1, disabled: true },
{ name: '尿常规', code: 2 },
{ name: '肝功能', code: 3 },
{ name: '肾功能', code: 4 },
{ name: '电解质', code: 5 }
]
} }
}, },
created() { created() {
......
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