Ver Fonte

1.封装pdf组件。 2.封装上传文件组件

jiaxiaoqiang há 1 ano atrás
pai
commit
50bc5b4332

+ 1 - 0
src/api/file/index.ts

@@ -10,6 +10,7 @@ import { FileInfo } from "./types";
 export function uploadFileApi(file: File): AxiosPromise<FileInfo> {
   const formData = new FormData();
   formData.append("file", file);
+  formData.append("fileName", file.name);
   return request({
     url: "/api/v1/base/upload",
     method: "post",

+ 89 - 0
src/components/PDFView/index.vue

@@ -0,0 +1,89 @@
+<template>
+  <el-button
+    v-if="contentType === 'button'"
+    :type="btnType"
+    :link="isLink"
+    @click="showPdf"
+  >
+    {{ btnText }}
+  </el-button>
+  <VuePdfEmbed
+    v-else
+    :source="pdfSource"
+    :page="pageNumber"
+    annotation-layer
+    text-layer
+    @click="showPdf"
+  />
+  <el-drawer
+    v-if="needToShowPdf"
+    v-model="visible"
+    :footer="false"
+    :header="false"
+    :show-close="false"
+    destroy-on-close
+    direction="rtl"
+    size="972px"
+  >
+    <VuePdfEmbed
+      :source="pdfSource"
+      :page="showPdfNumber"
+      annotation-layer
+      text-layer
+    />
+  </el-drawer>
+</template>
+
+<script lang="ts" setup>
+import VuePdfEmbed from "vue-pdf-embed";
+// essential styles
+import "vue-pdf-embed/dist/style/index.css";
+
+// optional styles
+import "vue-pdf-embed/dist/style/annotationLayer.css";
+import "vue-pdf-embed/dist/style/textLayer.css";
+
+// either URL, Base64, binary, or document proxy
+const props = defineProps({
+  pdfSource: {
+    type: String,
+    required: true,
+  },
+  pageNumber: {
+    type: Number,
+    default: 0,
+  },
+  needToShowPdf: {
+    type: Boolean,
+    default: false,
+  },
+  contentType: {
+    type: String as PropType<"button" | "pdf">,
+    default: "pdf",
+  },
+  btnText: {
+    type: String,
+    default: "预览",
+  },
+  btnType: {
+    type: String,
+    default: "primary",
+  },
+  isLink: {
+    type: Boolean,
+    default: false,
+  },
+  showPdfNumber: {
+    type: Number,
+    default: 0,
+  },
+});
+
+const visible = ref(false);
+
+const showPdf = () => {
+  visible.value = true;
+};
+</script>
+
+<style lang="scss" scoped></style>

+ 105 - 0
src/components/Upload/FilesUpload.vue

@@ -0,0 +1,105 @@
+<template>
+  <el-upload
+    v-model:file-list="fileList"
+    class="upload-demo"
+    :on-change="handleChange"
+    :limit="limit"
+    :auto-upload="false"
+    :show-file-list="false"
+  >
+    <el-button
+      type="primary"
+      :loading="loading"
+      :disabled="fileList.length >= limit"
+      >点击上传文件</el-button
+    >
+    <template #tip>
+      <div class="tip">
+        文件类型限制为.jpg,.jpeg,.png,word文档,pdf,大小不超过{{ size }}M
+      </div>
+    </template>
+    <div>
+      <el-tag
+        class="file-item"
+        v-for="(file, index) in fileList"
+        :key="file.name"
+        closable
+        type="success"
+        @close="deleteFile(index)"
+      >
+        {{ file.name }}
+      </el-tag>
+    </div>
+  </el-upload>
+</template>
+<script lang="ts" setup>
+import { ref } from "vue";
+
+const props = defineProps({
+  size: {
+    type: Number,
+    default: 4,
+  },
+  limit: {
+    type: Number,
+    default: 1,
+  },
+  src: {
+    type: String,
+    default: "",
+  },
+  srcList: {
+    type: Array,
+    default: [],
+  },
+});
+
+const loading = ref(false);
+
+const emit = defineEmits(["update:src", "update:srcList"]);
+
+// 上传文件成功返回的值
+const src = useVModel(props, "src", emit); //单文件用这个
+const srcList = useVModel(props, "srcList", emit); //多文件用这个
+
+import { UploadFile, UploadFiles, UploadUserFile } from "element-plus";
+import { uploadFileApi } from "@/api/file";
+
+// el-upload 绑定的值
+const fileList = ref<UploadUserFile[]>([]);
+
+const handleChange = async (uploadFile: UploadFile) => {
+  if (uploadFile.size! > props.size * 1048 * 1048) {
+    ElMessage.warning(`上传文件不能大于${props.size}M`);
+    return;
+  }
+  loading.value = true;
+  uploadFileApi(uploadFile.raw as File)
+    .then((res: any) => {
+      loading.value = false;
+      src.value = res.data.fileUrl;
+      srcList.value.push(res.data.fileUrl);
+    })
+    .catch((err) => {
+      ElMessage.error(err.message);
+      loading.value = false;
+    });
+};
+
+const deleteFile = (index: number) => {
+  src.value = ""; //删除直接清空src即可,不用考虑是哪个,因为单文件不会有多个
+  fileList.value.splice(index, 1);
+  srcList.value.splice(index, 1);
+};
+</script>
+
+<style scoped lang="scss">
+.tip {
+  font-size: 12px;
+  color: #e6a23c;
+  margin-top: 5px;
+}
+.file-item {
+  margin-left: 10px;
+}
+</style>

+ 4 - 4
src/components/Upload/SingleUpload.vue

@@ -40,19 +40,19 @@ const photoSource = ref<string>("");
  * @param options
  */
 async function uploadFile(options: UploadRequestOptions): Promise<any> {
-  const res = await uploadFileApi(options.file);
+  const res: any = await uploadFileApi(options.file);
   //绝对路径
   // imgUrl.value = import.meta.env.VITE_APP_UPLOAD_URL + res.data;
   //使用相对路径
-  imgUrl.value = res.data + "";
-  photoSource.value = import.meta.env.VITE_APP_UPLOAD_URL + res.data;
+  imgUrl.value = res.data.fileUrl + "";
+  photoSource.value = import.meta.env.VITE_APP_UPLOAD_URL + res.data.fileUrl;
 }
 
 /**
  * 限制用户上传文件的格式和大小
  */
 function handleBeforeUpload(file: UploadRawFile) {
-  if (file.size > 2 * 1048 * 1048) {
+  if (file.size > 4 * 1048 * 1048) {
     ElMessage.warning("上传图片不能大于2M");
     return false;
   }

+ 19 - 0
src/views/demo/hooksDemo.vue

@@ -72,6 +72,17 @@
       @selected-sure="onSelectedFinish"
     />
     <ExcelUpload ref="uploadRef" @finished="uploadFinished" />
+    <FilesUpload v-model:src="fileUrl" v-model:src-list="fileUrlList" />
+    <el-button @click="testFiles">测试上传文件的值</el-button>
+    <div style="height: 100px; width: 100px; overflow: hidden">
+      <PDFView
+        :need-to-show-pdf="true"
+        content-type="button"
+        :is-link="true"
+        :show-pdf-number="3"
+        pdf-source="http://192.168.101.4:9000/jgfile/2024/04/20/%E7%AC%AC08%E7%AB%A0_%E8%81%9A%E5%90%88%E5%87%BD%E6%95%B0.pdf"
+      />
+    </div>
   </div>
 </template>
 <script setup>
@@ -81,6 +92,14 @@ import dictDataUtil from "@/common/configs/dictDataUtil";
 import ButtonPermKeys from "@/common/configs/buttonPermission";
 import { useCommonStoreHook, useDictionaryStoreHook } from "@/store";
 import SingleUpload from "@/components/Upload/SingleUpload.vue";
+import PDFView from "@/components/PDFView/index.vue";
+// 测试上传文件相关
+const fileUrl = ref(""); //单文件
+const fileUrlList = ref([]); //多文件
+const testFiles = () => {
+  console.log("fileUrl", fileUrl.value);
+  console.log("fileUrlList", fileUrlList.value);
+};
 
 // 数据字典相关
 const { dicts } = useDictionaryStoreHook();