Sanakey
2021-01-31 53cc6f817625897935fb10c3845ad7be400f3036
提交 | 用户 | age
d98d05 1 import { VantComponent } from '../common/component';
53cc6f 2 import { isImageFile, chooseFile, isVideoFile } from './utils';
d98d05 3 import { chooseImageProps, chooseVideoProps } from './shared';
53cc6f 4 import { isBoolean, isPromise } from '../common/validator';
d98d05 5 VantComponent({
S 6   props: Object.assign(
7     Object.assign(
8       {
9         disabled: Boolean,
10         multiple: Boolean,
11         uploadText: String,
12         useBeforeRead: Boolean,
13         afterRead: null,
14         beforeRead: null,
15         previewSize: {
16           type: null,
53cc6f 17           value: 80,
d98d05 18         },
S 19         name: {
53cc6f 20           type: null,
d98d05 21           value: '',
S 22         },
23         accept: {
24           type: String,
25           value: 'image',
26         },
27         fileList: {
28           type: Array,
29           value: [],
30           observer: 'formatFileList',
31         },
32         maxSize: {
33           type: Number,
34           value: Number.MAX_VALUE,
35         },
36         maxCount: {
37           type: Number,
38           value: 100,
39         },
40         deletable: {
41           type: Boolean,
42           value: true,
43         },
44         showUpload: {
45           type: Boolean,
46           value: true,
47         },
48         previewImage: {
49           type: Boolean,
50           value: true,
51         },
52         previewFullImage: {
53           type: Boolean,
54           value: true,
55         },
56         imageFit: {
57           type: String,
58           value: 'scaleToFill',
59         },
60         uploadIcon: {
61           type: String,
62           value: 'photograph',
63         },
64       },
65       chooseImageProps
66     ),
67     chooseVideoProps
68   ),
69   data: {
70     lists: [],
71     isInCount: true,
72   },
73   methods: {
74     formatFileList() {
75       const { fileList = [], maxCount } = this.data;
76       const lists = fileList.map((item) =>
77         Object.assign(Object.assign({}, item), {
53cc6f 78           isImage: isImageFile(item),
S 79           isVideo: isVideoFile(item),
80           deletable: isBoolean(item.deletable) ? item.deletable : true,
d98d05 81         })
S 82       );
83       this.setData({ lists, isInCount: lists.length < maxCount });
84     },
85     getDetail(index) {
86       return {
87         name: this.data.name,
88         index: index == null ? this.data.fileList.length : index,
89       };
90     },
91     startUpload() {
53cc6f 92       const { maxCount, multiple, lists, disabled } = this.data;
d98d05 93       if (disabled) return;
S 94       chooseFile(
95         Object.assign(Object.assign({}, this.data), {
96           maxCount: maxCount - lists.length,
97         })
98       )
99         .then((res) => {
53cc6f 100           this.onBeforeRead(multiple ? res : res[0]);
d98d05 101         })
S 102         .catch((error) => {
103           this.$emit('error', error);
104         });
105     },
106     onBeforeRead(file) {
107       const { beforeRead, useBeforeRead } = this.data;
108       let res = true;
109       if (typeof beforeRead === 'function') {
110         res = beforeRead(file, this.getDetail());
111       }
112       if (useBeforeRead) {
113         res = new Promise((resolve, reject) => {
114           this.$emit(
115             'before-read',
116             Object.assign(Object.assign({ file }, this.getDetail()), {
117               callback: (ok) => {
118                 ok ? resolve() : reject();
119               },
120             })
121           );
122         });
123       }
124       if (!res) {
125         return;
126       }
127       if (isPromise(res)) {
128         res.then((data) => this.onAfterRead(data || file));
129       } else {
130         this.onAfterRead(file);
131       }
132     },
133     onAfterRead(file) {
53cc6f 134       const { maxSize, afterRead } = this.data;
d98d05 135       const oversize = Array.isArray(file)
S 136         ? file.some((item) => item.size > maxSize)
137         : file.size > maxSize;
138       if (oversize) {
139         this.$emit('oversize', Object.assign({ file }, this.getDetail()));
140         return;
141       }
53cc6f 142       if (typeof afterRead === 'function') {
S 143         afterRead(file, this.getDetail());
d98d05 144       }
S 145       this.$emit('after-read', Object.assign({ file }, this.getDetail()));
146     },
147     deleteItem(event) {
148       const { index } = event.currentTarget.dataset;
149       this.$emit(
150         'delete',
151         Object.assign(Object.assign({}, this.getDetail(index)), {
152           file: this.data.fileList[index],
153         })
154       );
155     },
156     onPreviewImage(event) {
157       if (!this.data.previewFullImage) return;
158       const { index } = event.currentTarget.dataset;
159       const { lists } = this.data;
160       const item = lists[index];
161       wx.previewImage({
53cc6f 162         urls: lists.filter((item) => isImageFile(item)).map((item) => item.url),
S 163         current: item.url,
d98d05 164         fail() {
S 165           wx.showToast({ title: '预览图片失败', icon: 'none' });
166         },
167       });
168     },
53cc6f 169     onPreviewVideo(event) {
S 170       if (!this.data.previewFullImage) return;
171       const { index } = event.currentTarget.dataset;
172       const { lists } = this.data;
173       wx.previewMedia({
174         sources: lists
175           .filter((item) => isVideoFile(item))
176           .map((item) =>
177             Object.assign(Object.assign({}, item), { type: 'video' })
178           ),
179         current: index,
180         fail() {
181           wx.showToast({ title: '预览视频失败', icon: 'none' });
182         },
183       });
184     },
185     onPreviewFile(event) {
186       const { index } = event.currentTarget.dataset;
187       wx.openDocument({
188         filePath: this.data.lists[index].url,
189         showMenu: true,
190       });
191     },
d98d05 192     onClickPreview(event) {
S 193       const { index } = event.currentTarget.dataset;
194       const item = this.data.lists[index];
195       this.$emit(
196         'click-preview',
197         Object.assign(Object.assign({}, item), this.getDetail(index))
198       );
199     },
200   },
201 });