jiazhengPdfUpload.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. <template>
  2. <view>
  3. <!-- 触发按钮 -->
  4. <slot name="trigger" :uploading="uploading">
  5. <button
  6. :disabled="uploading"
  7. @click="choosePdf"
  8. class="upload-btn"
  9. >
  10. {{ uploading ? '上传中...' : '上传PDF' }}
  11. </button>
  12. </slot>
  13. </view>
  14. </template>
  15. <script>
  16. export default {
  17. name: 'PdfUploader',
  18. props: {
  19. // 上传接口地址
  20. uploadUrl: {
  21. type: String,
  22. required: true
  23. },
  24. // 最大文件大小(单位:MB)
  25. maxSize: {
  26. type: Number,
  27. default: 50
  28. }
  29. },
  30. data() {
  31. return {
  32. uploading: false
  33. }
  34. },
  35. methods: {
  36. // 选择PDF文件
  37. async choosePdf() {
  38. if (this.uploading) return
  39. try {
  40. const [file] = await this.selectFile()
  41. await this.verifyFile(file)
  42. const result = await this.uploadFile(file)
  43. this.$emit('success', result)
  44. } catch (error) {
  45. this.$emit('error', error)
  46. this.showToast(error.message)
  47. }
  48. },
  49. // 选择文件
  50. selectFile() {
  51. return new Promise((resolve, reject) => {
  52. uni.chooseFile({
  53. count: 1,
  54. type: 'file',
  55. extension: ['pdf'],
  56. success: res => resolve(res.tempFiles),
  57. fail: () => reject(new Error('取消选择'))
  58. })
  59. })
  60. },
  61. // 验证文件
  62. verifyFile(file) {
  63. const maxBytes = this.maxSize * 1024 * 1024
  64. if (!file.type.includes('pdf')) {
  65. throw new Error('请选择PDF文件')
  66. }
  67. if (file.size > maxBytes) {
  68. throw new Error(`文件大小不能超过${this.maxSize}MB`)
  69. }
  70. return true
  71. },
  72. // 执行上传
  73. uploadFile(file) {
  74. this.uploading = true
  75. return new Promise((resolve, reject) => {
  76. uni.uploadFile({
  77. url: this.uploadUrl,
  78. filePath: file.path,
  79. name: 'file',
  80. formData: {
  81. filename: file.name
  82. },
  83. success: (res) => {
  84. if (res.statusCode === 200) {
  85. resolve(JSON.parse(res.data))
  86. } else {
  87. reject(new Error('上传失败'))
  88. }
  89. },
  90. fail: () => reject(new Error('网络错误')),
  91. complete: () => (this.uploading = false)
  92. })
  93. })
  94. },
  95. // 显示提示
  96. showToast(message) {
  97. uni.showToast({
  98. title: message,
  99. icon: 'none',
  100. duration: 3000
  101. })
  102. }
  103. }
  104. }
  105. </script>
  106. <style scoped>
  107. .upload-btn {
  108. background-color: #007AFF;
  109. color: white;
  110. padding: 10px 20px;
  111. border-radius: 5px;
  112. font-size: 14px;
  113. }
  114. .upload-btn[disabled] {
  115. background-color: #cccccc;
  116. }
  117. </style>
  118. <!-- <SimplePdfUploader
  119. upload-url="https://your-api.com/upload"
  120. :max-size="30"
  121. @success="handleSuccess"
  122. @error="handleError"
  123. >
  124. <!-- 自定义触发按钮 -->
  125. <template v-slot:trigger="{ uploading }">
  126. <button
  127. :disabled="uploading"
  128. class="custom-btn"
  129. >
  130. {{ uploading ? '正在上传...' : '选择PDF文件' }}
  131. </button>
  132. </template>
  133. </SimplePdfUploader> -->