index.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. <template>
  2. <view class="jnpf-file">
  3. <view class="jnpf-file-box" :style="{textAlign:align}">
  4. <view v-if="!detailed &&!disabled " class="jnpf-file-box-line">
  5. <lsj-upload :ref="lsjUpload" :childId="childId" :width="width" :height="height" :option="option"
  6. :size="fileSize" :formats="getFormats" :instantly="instantly" @uploadEnd="onuploadEnd"
  7. :lsjUpload="lsjUpload" v-if="!disabled" :sizeUnit="sizeUnit" :buttonText='buttonText'
  8. :class="{'jnpf-file-disabled':disabled}">
  9. <!-- #ifndef MP-WEIXIN -->
  10. <view>
  11. <u-button size="mini">{{buttonText}}</u-button>
  12. </view>
  13. <!-- #endif -->
  14. </lsj-upload>
  15. </view>
  16. <u-button size="mini" v-if="disabled" class="jnpf-file-disabled">{{buttonText}}</u-button>
  17. <view v-for='(item,index) in fileList' :key="index" class="jnpf-file-item u-type-primary u-flex u-line-1"
  18. @tap='downLoad(item)'>
  19. <view class="jnpf-file-item-txt u-line-1" v-if="item.fileSize">
  20. {{item.name+'('+`${jnpf.toFileSize(item.fileSize)}`+' )'}}
  21. </view>
  22. <view class="jnpf-file-item-txt u-line-1" v-else>{{item.name}}</view>
  23. <view class="closeBox u-flex-col" @click.stop="delFile(index)" v-if="!detailed && !disabled">
  24. <text class="icon-ym icon-ym-nav-close closeTxt u-flex"></text>
  25. </view>
  26. </view>
  27. <view class="tipText u-p-l-20">
  28. {{tipText}}
  29. </view>
  30. </view>
  31. </view>
  32. </template>
  33. <script>
  34. import {
  35. getDownloadUrl
  36. } from '@/api/common'
  37. import jnpf from '@/utils/jnpf'
  38. const imgTypeList = ['png', 'jpg', 'jpeg', 'bmp', 'gif']
  39. export default {
  40. name: 'jnpf-upload-img',
  41. inheritAttrs: false,
  42. props: {
  43. modelValue: {
  44. type: Array,
  45. default: () => ([])
  46. },
  47. disabled: {
  48. type: Boolean,
  49. default: false
  50. },
  51. limit: {
  52. type: [Number, String],
  53. default: 9
  54. },
  55. fileSize: {
  56. type: Number,
  57. default: 5
  58. },
  59. sizeUnit: {
  60. type: String,
  61. default: 'MB'
  62. },
  63. accept: {
  64. type: String,
  65. default: ''
  66. },
  67. pathType: {
  68. type: String,
  69. default: 'defaultPath'
  70. },
  71. tipText: {
  72. type: String,
  73. default: ''
  74. },
  75. isAccount: {
  76. type: Number,
  77. default: 0
  78. },
  79. folder: {
  80. type: String,
  81. default: ''
  82. },
  83. vModel: {
  84. type: String,
  85. default: ''
  86. },
  87. detailed: {
  88. type: Boolean,
  89. default: false
  90. },
  91. align: {
  92. type: String,
  93. default: 'right'
  94. },
  95. sortRule: {
  96. type: Array,
  97. default: () => ([])
  98. },
  99. timeFormat: {
  100. type: String,
  101. default: ''
  102. },
  103. buttonText: {
  104. type: String,
  105. default: '点击上传'
  106. }
  107. },
  108. data() {
  109. return {
  110. percent: '',
  111. fileList: [],
  112. // 上传接口参数
  113. option: {},
  114. params: {
  115. pathType: this.pathType,
  116. isAccount: this.isAccount,
  117. folder: this.folder,
  118. sortRule: (this.sortRule || []).join(),
  119. timeFormat: this.timeFormat,
  120. },
  121. // 选择文件后是否立即自动上传,true=选择后立即上传
  122. instantly: true,
  123. size: 30,
  124. list: [],
  125. deletable: false,
  126. childId: 'upload' + this.$u.guid(3, false, 2),
  127. lsjUpload: 'lsjUpload' + this.$u.guid(3, false, 2),
  128. width: '140rpx',
  129. height: '70rpx',
  130. }
  131. },
  132. computed: {
  133. baseURL() {
  134. return this.define.baseURL
  135. },
  136. comUploadUrl() {
  137. return this.define.comUploadUrl
  138. },
  139. getFormats() {
  140. let formats = this.accept
  141. formats = formats.replace("image/*", 'png,jpg,jpeg,bmp,gif,webp,psd,svg,tiff')
  142. formats = formats.replace("video/*", 'avi,wmv,mpg,mpeg,mov,rm,ram,swf,flv,mp4,wma,rm,rmvb,flv,mpg,mkv')
  143. formats = formats.replace("audio/*", 'mp3,wav,aif,midi,m4a')
  144. return formats
  145. },
  146. },
  147. created() {
  148. const token = uni.getStorageSync('token')
  149. this.option = {
  150. url: this.baseURL + '/api/file/Uploader/annex',
  151. name: 'file',
  152. header: {
  153. 'Authorization': token,
  154. 'uid': '27682',
  155. 'client': 'app',
  156. 'accountid': 'DP',
  157. },
  158. data: this.params
  159. }
  160. },
  161. watch: {
  162. modelValue: {
  163. handler(val) {
  164. this.fileList = JSON.parse(JSON.stringify(val));
  165. },
  166. immediate: true
  167. }
  168. },
  169. methods: {
  170. // 某文件上传结束回调(成功失败都回调)
  171. onuploadEnd(item) {
  172. if (item['responseText']) {
  173. let response = JSON.parse(item.responseText)
  174. if (this.fileList.length >= this.limit) return this.$u.toast('已达最大上传数量')
  175. if (response.code != 200) return this.$u.toast(response.msg)
  176. this.fileList.push({
  177. name: item.name,
  178. fileId: response.data.name,
  179. url: response.data.url,
  180. fileExtension: response.data.fileExtension,
  181. fileSize: response.data.fileSize
  182. })
  183. this.$emit('update:modelValue', this.fileList)
  184. this.$emit('change', this.fileList)
  185. }
  186. this.$forceUpdate();
  187. },
  188. downLoad(item) {
  189. if (item.fileExtension && imgTypeList.includes(item.fileExtension)) return this.previewImage(item)
  190. // #ifdef MP
  191. this.previewFile(item)
  192. // #endif
  193. // #ifndef MP
  194. getDownloadUrl('annex', item.fileId).then(res => {
  195. const fileUrl = this.baseURL + res.data.url + '&name=' + item.name;
  196. // #ifdef H5
  197. window.location.href = fileUrl;
  198. // #endif
  199. // #ifdef APP-PLUS
  200. this.downloadFile(res.data.url);
  201. // #endif
  202. })
  203. // #endif
  204. },
  205. // 移除某个文件
  206. delFile(index) {
  207. uni.showModal({
  208. title: '提示',
  209. content: '是否删除该文件?',
  210. success: res => {
  211. if (res.confirm) {
  212. this.fileList.splice(index, 1)
  213. this.$emit('update:modelValue', this.fileList)
  214. this.$emit('change', this.fileList)
  215. this.fileList.length >= this.fileCount ? this.deletable = true : this.deletable =
  216. false
  217. } else if (res.cancel) {}
  218. }
  219. });
  220. },
  221. previewFile(item) {
  222. let fileTypes = ['doc', 'xls', 'ppt', 'pdf', 'docx', 'xlsx', 'pptx']
  223. let url = item.url
  224. let fileType = url.split('.')[1]
  225. if (fileTypes.includes(fileType)) {
  226. uni.downloadFile({
  227. url: this.baseURL + url,
  228. success: (res) => {
  229. var filePath = res.tempFilePath;
  230. uni.openDocument({
  231. filePath: encodeURI(filePath),
  232. showMenu: true,
  233. fileType: fileType,
  234. success: (res) => {
  235. console.log('打开文档成功');
  236. },
  237. fail(err) {
  238. console.log('小程序', err);
  239. }
  240. });
  241. }
  242. });
  243. } else {
  244. this.$u.toast(
  245. '该文件类型无法打开'
  246. )
  247. }
  248. },
  249. previewImage(item) {
  250. if (!item.url) return
  251. const url = jnpf.getAuthImgUrl(item.url)
  252. uni.previewImage({
  253. urls: [url],
  254. current: url,
  255. success: () => {},
  256. fail: () => {
  257. uni.showToast({
  258. title: '预览图片失败',
  259. icon: 'none'
  260. });
  261. }
  262. });
  263. },
  264. downloadFile(url) {
  265. uni.downloadFile({
  266. url: this.baseURL + url,
  267. success: res => {
  268. if (res.statusCode === 200) {
  269. uni.saveFile({
  270. tempFilePath: res.tempFilePath,
  271. success: red => {
  272. uni.showToast({
  273. icon: 'none',
  274. mask: true,
  275. title: '文件已保存:' + red.savedFilePath, //保存路径
  276. duration: 3000,
  277. });
  278. setTimeout(() => {
  279. uni.openDocument({
  280. filePath: red.savedFilePath,
  281. success: ress => {},
  282. fail(err) {}
  283. });
  284. }, 500)
  285. }
  286. });
  287. }
  288. }
  289. });
  290. },
  291. }
  292. }
  293. </script>
  294. <style lang="scss" scoped>
  295. .jnpf-file {
  296. width: 100%;
  297. .jnpf-file-box {
  298. .jnpf-file-box-line {
  299. height: 70rpx;
  300. }
  301. .tipText {
  302. color: #606266;
  303. word-break: break-all;
  304. line-height: 48rpx;
  305. }
  306. .jnpf-file-item {
  307. justify-content: space-between;
  308. flex-direction: row;
  309. .jnpf-file-item-txt {
  310. width: 230rpx;
  311. flex: auto;
  312. }
  313. .showLeft {
  314. text-align: left;
  315. }
  316. .closeBox {
  317. height: 60rpx;
  318. align-items: flex-end;
  319. justify-content: space-evenly;
  320. flex: 0.2;
  321. .closeTxt {
  322. width: 36rpx;
  323. height: 36rpx;
  324. border-radius: 50%;
  325. background-color: #fa3534;
  326. color: #FFFFFF;
  327. font-size: 20rpx;
  328. align-items: center;
  329. justify-content: center;
  330. line-height: 36rpx;
  331. }
  332. }
  333. }
  334. }
  335. .jnpf-file-disabled {
  336. background-color: #E6E6E6 !important;
  337. border-color: #D9D9D9 !important;
  338. color: #9B9B9B !important;
  339. }
  340. }
  341. </style>