| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- <script setup lang="ts">
- import type { FormItemRule } from "element-plus/es/components/form/src/types"
- import type { VbFormItem, VbFormRowItem } from "@@@/form/models"
- const props = withDefaults(
- defineProps<{
- options?: any
- url?: string
- templateUrl?: string
- templateName?: string
- isAlertError?: boolean
- showUpdateCheckbox?: boolean // 是否显示 更新复选框
- accept?: string
- fileName?: string
- headers?: any
- title?: string
- saveAutoClose?: boolean
- formData?: any
- formRowItems?: VbFormRowItem[]
- formItems?: VbFormItem[]
- formRules?: Record<string, FormItemRule[]>
- formLabelWidth?: string | number // 表单label宽度
- formSize?: "large" | "default" | "small"
- gutter?: number
- span?: number
- formProps?: object
- formListeners?: object
- modalFormClass?: string
- modalFormStyle?: string
- isValidateForm?: boolean //验证表单
- params?: object | (() => {})
- appendToBody?: boolean
- }>(),
- {
- title: "",
- headers: () => {
- return {
- Authorization: "Bearer " + getToken(),
- ClientId: import.meta.env.VITE_APP_CLIENT_ID
- }
- },
- accept: ".xlsx, .xls",
- templateUrl: "",
- templateName: "",
- fileName: "file",
- isAlertError: true,
- appendToBody: true,
- showUpdateCheckbox: false,
- isValidateForm: true,
- saveAutoClose: true,
- formLabelWidth: "100px",
- formSize: "large",
- modalFormClass: "vb-form",
- modalFormStyle: ""
- }
- )
- const emits = defineEmits<{
- (e: "modelValue:value", v: string): void
- (e: "update:formData", data: any): boolean
- (e: "onProgress", event: any, file: any, fileList: any): void
- (e: "onSuccess", response: any, file: any, fileList: any): void
- (e: "onError", error: Error, file: any, fileList: any): void
- (e: "onConfirm"): void
- }>()
- const { formData } = toRefs(props)
- const modalFormRef = ref<HTMLFormElement>()
- const uploadModalRef = ref()
- const uploadRef = ref()
- const uploadUpdateSupport = ref(false)
- const isUploading = ref(false)
- const opts = ref<any>({})
- const url = computed(() => {
- let queryParams = "?t=" + new Date().getTime()
- if (opts.value.showUpdateCheckbox) {
- queryParams += `&updateSupport=${uploadUpdateSupport.value}`
- }
- if (opts.value.params) {
- const data =
- typeof opts.value.params === "function"
- ? opts.value.params()
- : typeof opts.value.params === "object"
- ? props.params
- : {}
- for (const key in data) {
- if (data.hasOwnProperty(key)) {
- queryParams += `&${key}=${data[key]}`
- }
- }
- }
- // if (formData.value) {
- // for (const key in formData.value) {
- // if (formData.value.hasOwnProperty(key)) {
- // queryParams += `&${key}=${formData.value[key]}`
- // }
- // }
- // }
- return `${opts.value.url}${queryParams}`
- })
- function submitUpload() {
- if (modalFormRef.value && props.isValidateForm) {
- modalFormRef.value.validate().then((valid: boolean) => {
- if (valid) {
- uploadRef.value.submit()
- emits("onConfirm")
- if (props.saveAutoClose) {
- uploadModalRef.value.hide()
- }
- } else {
- console.error("UPLOAD_FORM 验证失败")
- }
- })
- } else {
- uploadRef.value.submit()
- emits("onConfirm")
- if (props.saveAutoClose) {
- uploadModalRef.value.hide()
- }
- }
- }
- /** 文件上传中处理 */
- function handleFileUploadProgress(event: any, file: any, fileList: any) {
- isUploading.value = true
- message.loading()
- emits("onProgress", event, file, fileList)
- }
- /** 文件上传成功处理 */
- function handleFileSuccess(response: any, file: any, fileList: any) {
- isUploading.value = false
- uploadRef.value.handleRemove(file)
- message.alert(
- "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
- response.msg +
- "</div>",
- "导入结果",
- { dangerouslyUseHTMLString: true }
- )
- message.closeLoading()
- emits("onSuccess", response, file, fileList)
- }
- function handleFileError(error: Error, file: any, fileList: any) {
- message.closeLoading()
- if (opts.value.isAlertError) {
- message.msgError(error.message)
- }
- emits("onError", error, file, fileList)
- }
- function importTemplate() {
- download(
- opts.value.templateUrl,
- `${opts.value.templateName}_TEMPLATE_${new Date().getTime()}.xlsx`
- )
- }
- function getUploadData() {
- return formData.value
- }
- //form表单的插槽 需要_form结尾,并去掉_form传递给VbForm组件
- function isFormSlot(v: string | number): string | undefined {
- let str
- const formSlotSuffix = "_form"
- v = v as string
- if (v.search(formSlotSuffix) > 0) {
- str = v.substring(0, v.length - formSlotSuffix.length)
- }
- return str
- }
- function init() {
- opts.value = props.options ? Object.assign({}, props, props.options) : props
- if (!opts.value.url) {
- throw new Error("uploadUrl不能为空!")
- }
- }
- function show() {
- uploadModalRef.value.show()
- }
- onMounted(init)
- defineExpose({ show })
- </script>
- <template>
- <VbModal
- v-model:modal="uploadModalRef"
- :title="opts.title"
- :save-auto-close="false"
- @confirm="submitUpload"
- :append-to-body="appendToBody"
- v-bind="$attrs">
- <template #body>
- <slot name="params_form"></slot>
- <VbForm
- v-if="formRowItems || formItems"
- ref="modalFormRef"
- v-model:data="formData"
- :row-items="formRowItems"
- :items="formItems"
- :label-width="formLabelWidth"
- :rules="formRules"
- :size="formSize"
- :class="modalFormClass"
- :style="modalFormStyle"
- :span="span"
- :gutter="gutter"
- v-bind="formProps"
- v-on="formListeners">
- <template v-for="(_, name) in $slots" #[`${isFormSlot(name)}`]>
- <slot v-if="isFormSlot(name)" :name="name" />
- </template>
- </VbForm>
- <el-upload
- ref="uploadRef"
- :limit="1"
- :accept="opts.accept"
- :headers="opts.headers"
- :action="url"
- :name="opts.fileName"
- :data="getUploadData"
- :disabled="isUploading"
- :on-progress="handleFileUploadProgress"
- :on-success="handleFileSuccess"
- :on-error="handleFileError"
- :auto-upload="false"
- drag>
- <el-icon class="el-icon--upload"><upload-filled /></el-icon>
- <div class="el-upload__text">
- 将文件拖到此处,或
- <em>点击上传</em>
- </div>
- <template #tip>
- <div class="el-upload__tip text-center">
- <div class="el-upload__tip">
- <el-checkbox v-if="opts.showUpdateCheckbox" v-model="uploadUpdateSupport" />
- 是否更新已经存在的数据
- </div>
- <span>仅允许导入{{ opts.accept }}格式文件。</span>
- <el-link
- v-if="opts.templateUrl"
- type="primary"
- :underline="false"
- style="font-size: 12px; vertical-align: baseline"
- @click="importTemplate">
- 下载模板
- </el-link>
- </div>
- </template>
- </el-upload>
- </template>
- </VbModal>
- </template>
|